[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

'gets' has been hijacked

Pete Elmore

6/6/2005 7:32:00 PM

I was working with a simple script, that unexpectedly broke. The
problem can be reduced to this:

pete@robots:~$ cat t.rb
#!/usr/bin/env ruby
p gets
pete@robots:~$ ./t.rb
asdf
"asdf\n"
pete@robots:~$ ./t.rb nonexistent-file
/t.rb:2:in `gets': No such file or directory - nonexistent-file
(Errno::ENOENT)
from ./t.rb:2

Ah, right, I remember this from the Bad Old Days of Perl: stdin has been
stolen. Is there any way to stop this behavior, like a global I could
set or a flag I could pass to ruby? Couldn't find anything on the man
page or in Pickaxe.


6 Answers

Stefan Lang

6/6/2005 7:37:00 PM

0

On Monday 06 June 2005 21:31, Pete Elmore wrote:
> I was working with a simple script, that unexpectedly broke. The
> problem can be reduced to this:
>
> pete@robots:~$ cat t.rb
> #!/usr/bin/env ruby
> p gets
> pete@robots:~$ ./t.rb
> asdf
> "asdf\n"
> pete@robots:~$ ./t.rb nonexistent-file
> ./t.rb:2:in `gets': No such file or directory - nonexistent-file
> (Errno::ENOENT)
> from ./t.rb:2
>
> Ah, right, I remember this from the Bad Old Days of Perl: stdin has been
> stolen. Is there any way to stop this behavior, like a global I could
> set or a flag I could pass to ruby? Couldn't find anything on the man
> page or in Pickaxe.

You could explicitely call #readline on $stdin instead of Kernel#gets:
$stdin.readline

Stefan


James Gray

6/6/2005 7:40:00 PM

0

On Jun 6, 2005, at 2:31 PM, Pete Elmore wrote:

> I was working with a simple script, that unexpectedly broke. The
> problem can be reduced to this:
>
> pete@robots:~$ cat t.rb
> #!/usr/bin/env ruby
> p gets
> pete@robots:~$ ./t.rb
> asdf
> "asdf\n"
> pete@robots:~$ ./t.rb nonexistent-file
> ./t.rb:2:in `gets': No such file or directory - nonexistent-file
> (Errno::ENOENT)
> from ./t.rb:2
>
> Ah, right, I remember this from the Bad Old Days of Perl: stdin has
> been stolen. Is there any way to stop this behavior, like a global
> I could set or a flag I could pass to ruby? Couldn't find anything
> on the man page or in Pickaxe.

gets() as you're using it calls Kernel.gets(), which basically
amounts to ARGF.gets(). That's very handy for building Unix filters.

If your intention is to read from the keyboard only, just make sure
call gets() on STDIN with STDIN.gets() or $stdin.gets().

Hope that helps.

James Edward Gray II


Pete Elmore

6/6/2005 7:50:00 PM

0

James Edward Gray II wrote:
> If your intention is to read from the keyboard only, just make sure
> call gets() on STDIN with STDIN.gets() or $stdin.gets()
Yeah, that's what I'm doing. What I was wondering was if there was
something I could do to point Kernel#gets back at stdin.


James Gray

6/6/2005 7:58:00 PM

0

On Jun 6, 2005, at 2:49 PM, Pete Elmore wrote:

> James Edward Gray II wrote:
>
>> If your intention is to read from the keyboard only, just make
>> sure call gets() on STDIN with STDIN.gets() or $stdin.gets()
>>
> Yeah, that's what I'm doing. What I was wondering was if there was
> something I could do to point Kernel#gets back at stdin.

I'm sure there is. Off the top of my head (untested!):

module Kernel
def gets() $stdin.gets end
end

But why not just ask Ruby for what you really meant in the first
place? ;)

James Edward Gray II


Mark Hubbart

6/6/2005 8:44:00 PM

0

On 6/6/05, James Edward Gray II <james@grayproductions.net> wrote:
> On Jun 6, 2005, at 2:31 PM, Pete Elmore wrote:
>
> > I was working with a simple script, that unexpectedly broke. The
> > problem can be reduced to this:
> >
> > pete@robots:~$ cat t.rb
> > #!/usr/bin/env ruby
> > p gets
> > pete@robots:~$ ./t.rb
> > asdf
> > "asdf\n"
> > pete@robots:~$ ./t.rb nonexistent-file
> > ./t.rb:2:in `gets': No such file or directory - nonexistent-file
> > (Errno::ENOENT)
> > from ./t.rb:2
> >
> > Ah, right, I remember this from the Bad Old Days of Perl: stdin has
> > been stolen. Is there any way to stop this behavior, like a global
> > I could set or a flag I could pass to ruby? Couldn't find anything
> > on the man page or in Pickaxe.
>
> gets() as you're using it calls Kernel.gets(), which basically
> amounts to ARGF.gets(). That's very handy for building Unix filters.

expanding on that: ARGF *is* STDIN when there are no files specified:

mark@eMac% ruby -e'p ARGF.fileno == STDIN.fileno'
true
mark@eMac% ruby -e'p ARGF.fileno == STDIN.fileno' /etc/hosts
false

> If your intention is to read from the keyboard only, just make sure
> call gets() on STDIN with STDIN.gets() or $stdin.gets().
>
> Hope that helps.
>
> James Edward Gray II
>
>


Pete Elmore

6/6/2005 9:10:00 PM

0

James Edward Gray II wrote:
> I'm sure there is. Off the top of my head (untested!):
>
> module Kernel
> def gets() $stdin.gets end
> end
Ah, thanks. I'll probably just keep using $stdin.gets if there's not a
really clean way.
> But why not just ask Ruby for what you really meant in the first
> place? ;)
puts always goes to $stdout (well, $defout), so I thought that gets
would read $stdin, or it would be possible to nicely ask it to do so. I
don't mind $stdin.gets, but it seems a little odd. (I realize that I'm
treading dangerously close to POLSland, so I'll stop. :)
> Hope that helps.
I'm always thankful to the community for tolerating my endless stream of
n00b questions. :)