Chomping and stomping


#1

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.


#2

On 2/2/06, John M. removed_email_address@domain.invalid wrote:

chomper
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 F.


#3

John M. wrote:

xx

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


#4

On Fri, 3 Feb 2006, William J. wrote:

puts "hit me with a squirell!"

#!/usr/bin/ruby -w

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 methodchomp’ called for nil:NilClass
(NoMethodError)
from a.rb:9

nil doesn’t like that! :wink:

-a


#5

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. :slight_smile:

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


#6

On 2/2/06, removed_email_address@domain.invalid removed_email_address@domain.invalid wrote:

harp:~ > ruby a.rb < /dev/null
a.rb:3:in chomper': private methodchomp’ called for nil:NilClass (NoMethodError)
from a.rb:9

nil doesn’t like that! :wink:

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 F.


#7

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

On 2/2/06, removed_email_address@domain.invalid removed_email_address@domain.invalid wrote:

harp:~ > ruby a.rb < /dev/null
a.rb:3:in chomper': private methodchomp’ called for
nil:NilClass (NoMethodError)
from a.rb:9

nil doesn’t like that! :wink:

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 G. II


#8

On Fri, 3 Feb 2006, James Edward G. II wrote:

Heh, yeah, I glossed over that too. You really need to check the
break if xx == ‘qq’

puts “Hit me with a squirrel!”
end
end

golfing

def chomper() STDIN.detect{|x| x =~ /^qq/ or puts “hit me”} end

-a


#9

William J. wrote:

xx = gets.chomp!

def chomper
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


#10

removed_email_address@domain.invalid wrote:

xx = gets.chomp!
in there?
#this don’t work.

harp:~ > ruby a.rb < /dev/null
a.rb:3:in chomper': private methodchomp’ 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.


#11

On 2/2/06, William J. removed_email_address@domain.invalid 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 F.

PS. And let’s not golf with this please…


#12

William J. wrote:

puts "hit me with a squirell!"

#!/usr/bin/ruby -w

puts “Hit me!” while gets and $.chomp! != “qq”
$
if $_
end

def chomper
puts “Hit me!” while gets and $.chomp! != “qq”
$

end


#13

On 2/2/06, William J. removed_email_address@domain.invalid wrote:

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

Well, in Ara’s defense I would claim that prefixing the command with
“harp:~ >” and using “/dev/null” both should be clear indicators that
he’s talking about a *nix system.

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.

This problem is not only due to no input. The same error will arise if
you reach EOF before matching the expected line. Try this:

echo “Hello” | ruby a.rb

It is reasonable to expect a program that requires input to function
properly when invalid input is provided. Maybe the proper action is to
raise an error, but it should be a contextually appropriate error.

Jacob F.


#14

On Fri, 3 Feb 2006, William J. wrote:

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.

indeed. that’s what specifying cat and /dev/null does in and least four
ways:

cat, the most ubiquitous of unix programs => *nix
/ as file separator => *nix
/dev file system => *nix
/dev/null device => *nix

:wink:

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.

that’s not what is happening. reading from /dev/null or nul is the same
as
reading from an empty file. the key point i was illustrating, and the
bug in
the program, is that is fails at eof regardless if input is given.

for example, if i run this from the shell and type ‘ctrl-d’ to signal
end of
input (on unix)

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
a.rb:2:in chomper': private methodchomp’ called for nil:NilClass
(NoMethodError)
from a.rb:8

running on an empty file does the same

harp:~ > touch empty
harp:~ > ruby a.rb < empty
a.rb:2:in chomper': private methodchomp’ called for nil:NilClass
(NoMethodError)
from a.rb:8

as does running with some input

harp:~ > echo 42 > input

harp:~ > ruby a.rb < input
hit me with a squirell!
a.rb:2:in chomper': private methodchomp’ called for nil:NilClass
(NoMethodError)
from a.rb:8

in fact, it cannot be made to work with any input

it’s important, imho only perhaps, to show working code (best done by
actually
showing a run) unless that code is noted to be un-tested. i make
efforts to do
this for all examples i post:

http://groups.google.com/group/comp.lang.ruby/search?q=howard+cat+a.rb&start=0&scoring=d&

some probably find it anoying but i make too many mistakes otherwise.

kind regards.

-a


#15

On 2/2/06, William J. removed_email_address@domain.invalid wrote:

Jacob F. wrote:

PS. And let’s not golf with this please…

If you don’t like golf, why watch it?

Because the original poster was asking for advice on why it wasn’t
working, not for a golfing contest.

Jacob F.


#16

Jacob F. wrote:

On 2/2/06, William J. removed_email_address@domain.invalid wrote:

Jacob F. wrote:

PS. And let’s not golf with this please…

If you don’t like golf, why watch it?

Because the original poster was asking for advice on why it wasn’t
working, not for a golfing contest.

The fact that his expectations were modest doesn’t mean that
I shouldn’t give him a bonus. One never has to ask for a golfing
contest, since those who enjoy programming and who test their
code before they post are always willing to indulge in that pastime.


#17

Jacob F. wrote:

On 2/2/06, William J. removed_email_address@domain.invalid 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”.

It works under ruby 1.8.2 (2004-05-19) [i386-mswin32].
Did you test it? The code you posted earlier doesn’t work:

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

puts chomper

Always test the code that you post, please.

Jacob F.

PS. And let’s not golf with this please…

If you don’t like golf, why watch it?

def chomper
puts “Hit me!” while gets.chomp! != “qq”
$_
end