[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

Chomping and stomping

John Maclean

2/2/2006 3:12:00 PM

Chaps,

Here's a short script to keep requesting for input...

#!/usr/bin/ruby -w
def chomper
xx = gets.chomp!
until $_ == "qq"
puts "hit me with a squirell!"
xx = gets.chomp!
xx
end
end

chomper

# this works but surely there must be a way to incoporate a variable
in there?

#!/usr/bin/ruby -w
def chomper
xx = gets.chomp!
until xx == "qq"
puts "hit me with a squirell!"
xx
end
end

#this don't work.

--
John Maclean
MSc (DIC)
07739 171 531



16 Answers

Jacob Fugal

2/2/2006 5:16:00 PM

0

On 2/2/06, John Maclean <info@jayeola.org> wrote:
> #!/usr/bin/ruby -w
> def chomper
> xx = gets.chomp!
> until $_ == "qq"
> puts "hit me with a squirell!"
> xx = gets.chomp!
> xx
> end
> end
>
> chomper
>
> # this works but surely there must be a way to incoporate a variable
> in there?
>
> #!/usr/bin/ruby -w
> def chomper
> xx = gets.chomp!
> until xx == "qq"
> puts "hit me with a squirell!"
> xx
> end
> end
>
> #this don't work.

String#chomp! is a "destructive" operation. This means that it acts in
place on its receiver and, in this case, returns nil. So what's
happening here is that Kernel#gets creates a String object, chomp! is
sent to that object, the object is modified in place and nil returned.
That's why xx is nil. As you discovered in your first example, the
String object returned by Kernel#gets is stored in $_. Accessing it
this way isn't a bset practice however.

What you probably want instead is to use the non-destructive twin (the
Good Twin) of String#chomp!, namely String#chomp. Notice the lack of
the bang (!). The bang is generally (but not always) an indicator that
the method is destructive. String#chomp creates a chomped copy of it's
receiver and returns it. Replacing chomp! with chomp it should work:

#!/usr/bin/ruby -w
def chomper
xx = gets.chomp
until xx == "qq"
puts "hit me with a squirell!"
xx
end
end

puts chomper

Jacob Fugal


William James

2/2/2006 5:26:00 PM

0


John Maclean wrote:
> Chaps,
>
> Here's a short script to keep requesting for input...
>
> #!/usr/bin/ruby -w
> def chomper
> xx = gets.chomp!
> until $_ == "qq"
> puts "hit me with a squirell!"
> xx = gets.chomp!
> xx
> end
> end
>
> chomper
>
> # this works but surely there must be a way to incoporate a variable
> in there?
>
> #!/usr/bin/ruby -w
> def chomper
> xx = gets.chomp!
> until xx == "qq"
> puts "hit me with a squirell!"
> xx
> end
> end
>
> #this don't work.


def chomper
until (xx = gets.chomp) == 'qq'
puts "hit me with a squirell!"
end
xx
end

puts chomper

Ara.T.Howard

2/2/2006 5:38:00 PM

0

Jacob Fugal

2/2/2006 5:59:00 PM

0

On 2/2/06, ara.t.howard@noaa.gov <ara.t.howard@noaa.gov> wrote:
> harp:~ > ruby a.rb < /dev/null
> a.rb:3:in `chomper': private method `chomp' called for nil:NilClass (NoMethodError)
> from a.rb:9
>
> nil doesn't like that! ;-)

Heh, yeah, I glossed over that too. You really need to check the
result of gets before you chomp it. This is the way I'd write John's
original loop (same semantics):

def chomper
while xx = gets
xx.chomp!
break if xx == 'qq'
puts "hit me with a squirell!"
end
xx
end

and the way I'd write it for myself (different semantics, mostly same intent):

def chomped_gets
(s = gets) and s.chomp
end

def chomper
loop do
puts "hit me with a squirell!"
break unless xx = chomped_gets
return xx if xx == 'qq'
end
end

Jacob Fugal


John Maclean

2/2/2006 6:30:00 PM

0

Chaps,

Thanks for those speedy replies
Following on from

#thanks to you guyson the list for clearing this up
jayeola@tp20$ cat bin/acid/classes/testing/testchomp.rb
#!/usr/bin/ruby -w
def chomper
xx = gets.chomp
until (xx= gets.chomp) == "qq"
puts "hit me with a squirell!"
end
xx
end


chomper
# ^^ the above works. :)

# This is supposed to do the same as the above but write to a file...

here's version 1
#!/usr/bin/ruby -w

def testwrite
puts "hit me with a squirell!"
until $_ =="qq"
gets.chomp!
if $_ != "qq"
File.open("testfile", "a") { |file| file.write($_) }
end
end
end
testwrite

here's version 1

jayeola@tp20$ cat bin/acid/classes/testing/write_file2.rb
#!/usr/bin/ruby -w

def testwrite
xx = gets.chomp
until (xx.gets.chomp) == "qq"
puts "hit me with a squirell!"
File.open("testfile", "a") { |file| file.write(xx) }
end
end

testwrite





On Fri, 3 Feb 2006 02:16:11 +0900
Jacob Fugal <lukfugl@gmail.com> wrote:

> On 2/2/06, John Maclean <info@jayeola.org> wrote:
> > #!/usr/bin/ruby -w
> > def chomper
> > xx = gets.chomp!
> > until $_ == "qq"
> > puts "hit me with a squirell!"
> > xx = gets.chomp!
> > xx
> > end
> > end
> >
> > chomper
> >
> > # this works but surely there must be a way to incoporate a variable
> > in there?
> >
> > #!/usr/bin/ruby -w
> > def chomper
> > xx = gets.chomp!
> > until xx == "qq"
> > puts "hit me with a squirell!"
> > xx
> > end
> > end
> >
> > #this don't work.
>
> String#chomp! is a "destructive" operation. This means that it acts in
> place on its receiver and, in this case, returns nil. So what's
> happening here is that Kernel#gets creates a String object, chomp! is
> sent to that object, the object is modified in place and nil returned.
> That's why xx is nil. As you discovered in your first example, the
> String object returned by Kernel#gets is stored in $_. Accessing it
> this way isn't a bset practice however.
>
> What you probably want instead is to use the non-destructive twin (the
> Good Twin) of String#chomp!, namely String#chomp. Notice the lack of
> the bang (!). The bang is generally (but not always) an indicator that
> the method is destructive. String#chomp creates a chomped copy of it's
> receiver and returns it. Replacing chomp! with chomp it should work:
>
> #!/usr/bin/ruby -w
> def chomper
> xx = gets.chomp
> until xx == "qq"
> puts "hit me with a squirell!"
> xx
> end
> end
>
> puts chomper
>
> Jacob Fugal
>
>
>


--
John Maclean
MSc (DIC)
07739 171 531



James Gray

2/2/2006 6:36:00 PM

0

On Feb 2, 2006, at 11:59 AM, Jacob Fugal wrote:

> On 2/2/06, ara.t.howard@noaa.gov <ara.t.howard@noaa.gov> wrote:
>> harp:~ > ruby a.rb < /dev/null
>> a.rb:3:in `chomper': private method `chomp' called for
>> nil:NilClass (NoMethodError)
>> from a.rb:9
>>
>> nil doesn't like that! ;-)
>
> Heh, yeah, I glossed over that too. You really need to check the
> result of gets before you chomp it.

Isn't this why we have iterators in Ruby? We get to avoid all these
messy loop ending tests...

> This is the way I'd write John's original loop (same semantics):
>
> def chomper
> while xx = gets
> xx.chomp!
> break if xx == 'qq'
> puts "hit me with a squirell!"
> end
> xx
> end

def chomper
$stdin.each do |line|
line.chomp!

return line if line == "qq"

puts "Hit me with a squirrel!"
end
end

James Edward Gray II


William James

2/2/2006 7:09:00 PM

0

William James wrote:
> John Maclean wrote:
> > Chaps,
> >
> > Here's a short script to keep requesting for input...
> >
> > #!/usr/bin/ruby -w
> > def chomper
> > xx = gets.chomp!
> > until $_ == "qq"
> > puts "hit me with a squirell!"
> > xx = gets.chomp!
> > xx
> > end
> > end
> >
> > chomper
> >
> > # this works but surely there must be a way to incoporate a variable
> > in there?
> >
> > #!/usr/bin/ruby -w
> > def chomper
> > xx = gets.chomp!
> > until xx == "qq"
> > puts "hit me with a squirell!"
> > xx
> > end
> > end
> >
> > #this don't work.
>
>
> def chomper
> until (xx = gets.chomp) == 'qq'
> puts "hit me with a squirell!"
> end
> xx
> end
>
> puts chomper

def chomper
puts "Hit me!" while gets and $_.chomp! != "qq"
$_ if $_
end

Ara.T.Howard

2/2/2006 7:39:00 PM

0

William James

2/2/2006 7:40:00 PM

0

ara.t.howard@noaa.gov wrote:
> On Fri, 3 Feb 2006, William James wrote:
>
> >
> > John Maclean wrote:
> >> Chaps,
> >>
> >> Here's a short script to keep requesting for input...
> >>
> >> #!/usr/bin/ruby -w
> >> def chomper
> >> xx = gets.chomp!
> >> until $_ == "qq"
> >> puts "hit me with a squirell!"
> >> xx = gets.chomp!
> >> xx
> >> end
> >> end
> >>
> >> chomper
> >>
> >> # this works but surely there must be a way to incoporate a variable
> >> in there?
> >>
> >> #!/usr/bin/ruby -w
> >> def chomper
> >> xx = gets.chomp!
> >> until xx == "qq"
> >> puts "hit me with a squirell!"
> >> xx
> >> end
> >> end
> >>
> >> #this don't work.
> >
> >
> > def chomper
> > until (xx = gets.chomp) == 'qq'
> > puts "hit me with a squirell!"
> > end
> > xx
> > end
> >
> > puts chomper
>
>
> harp:~ > cat a.rb
> def chomper
> until (xx = gets.chomp) == 'qq'
> puts "hit me with a squirell!"
> end
> xx
> end
>
> puts chomper
>
>
> harp:~ > ruby a.rb < /dev/null
> a.rb:3:in `chomper': private method `chomp' called for nil:NilClass (NoMethodError)
> from a.rb:9

The error I get in a dos-box is
The system cannot find the path specified.

To produce the error you gave, I must do it this way:
ruby a.rb < nul:

When you post something that depends upon a particular
operating system, you need to make that dependency clear.

It is reasonable to write a program that requires input.
It is not reasonable to expect a program that requires input to
function properly when you deliberately deprive it of input.

Jacob Fugal

2/2/2006 7:42:00 PM

0

On 2/2/06, William James <w_a_x_man@yahoo.com> wrote:
> def chomper
> puts "Hit me!" while gets and $_.chomp! != "qq"
> $_ if $_
> end

This will always loop until EOF and then return nil. $_.chomp! (as
opposed to $_.chomp) returns nil, and nil != "qq".

Jacob Fugal

PS. And let's not golf with this please...