Newbie questions

I feel like we need a Forum called, “Ruby N.” for people like me. Is
there one?

I am hoping someone could help me with the following (probably) simple
questions (my nested questions are surrounded by **):

  1. Someone said to use the following code for getting a string and
    printing to the screen:

puts “Where do you live?”
STDOUT.flush
city = gets.chomp
puts "I live in " + city

why not just do this:

puts “Where do you live?”
city = gets()
puts "I live in " + city

??

regarding STDOUT: the comment was made - STDOUT is a global constant
which is the actual standard output stream for the program.

but is it necessary?

A comment was made: flush flushes any buffered data within io to the
underlying operating system (note that this is Ruby internal buffering
only; the OS may buffer the data as well). The usage is not mandatory
but recommended.

I still don’t understand why flush is recommended. Is my omission
going to create a problem?

I understand chomp to remove record separators from the end, is there
another reason besides?

  1. Is there a place I can go to learn more about regular expressions?
  2. In IRB, Float::DIG => 15
    **question: This is because float displays to 15 decimals, right?
    **question: I see “::” all the time, but don’t understand it. What does
    :: mean? Is it showing hierarchy?
  3. In the code below:

class NameIt
def initialize(name)
@name = name
end
def to_s
puts “My name is: #{@name}”
end
end

n1 = NameIt.new(“tom”)
n2 = NameIt.new(“sally”)

n1.to_s
n2.to_s

**the last 4 lines seem very repetative. this is something I’ve wondered
for a long time. Is there a way to compact the last 4 lines if you are
trying to list a whole bunch of names at once using the method to_s?

thank very much!

Jason

On Fri, May 16, 2008 at 10:52 AM, Jason L.
[email protected] wrote:

STDOUT.flush
city = gets.chomp
puts "I live in " + city

why not just do this:

puts “Where do you live?”
city = gets()
puts "I live in " + city

or…

puts “Where do you live?”
puts "You live in " << gets

only; the OS may buffer the data as well). The usage is not mandatory
but recommended.

I still don’t understand why flush is recommended. Is my omission
going to create a problem?

I understand chomp to remove record separators from the end, is there
another reason besides?

  1. Is there a place I can go to learn more about regular expressions?

I’ve occasionally found www.regexp.info useful.

  1. In IRB, Float::DIG => 15
    **question: This is because float displays to 15 decimals, right?
    **question: I see “::” all the time, but don’t understand it. What does
    :: mean? Is it showing hierarchy?

It’s the scope operator. Page 330 of the Pickaxe, 2nd Ed.

  1. In the code below:

class NameIt
def initialize(name)
@name = name
end
def to_s
puts “My name is: #{@name}”
end

def to_s
"My name is: " << name
# no puts
end

end

n1 = NameIt.new(“tom”)
n2 = NameIt.new(“sally”)

n1.to_s
n2.to_s

puts n1
puts n2

**the last 4 lines seem very repetative. this is something I’ve wondered
for a long time. Is there a way to compact the last 4 lines if you are
trying to list a whole bunch of names at once using the method to_s?

thank very much!

Jason

Todd

On 5/16/08, Jason L. [email protected] wrote:

I feel like we need a Forum called, “Ruby N.” for people like me. Is
there one?

This one usually works fine.

puts “Where do you live?”
city = gets()
puts "I live in " + city

??

regarding STDOUT: the comment was made - STDOUT is a global constant
which is the actual standard output stream for the program.

but is it necessary?

probably not for a simple test application like that one.

A comment was made: flush flushes any buffered data within io to the
underlying operating system (note that this is Ruby internal buffering
only; the OS may buffer the data as well). The usage is not mandatory
but recommended.

I still don’t understand why flush is recommended. Is my omission
going to create a problem?

It’s possible that on some systems, the string “Where…?” would stay
in an internal buffer and not get printed. If that happened, your
program would be waiting for input, but the user would have no idea
what it wanted.
If you wanted a robust multi-platform application, a flush would
ensure that the string was printed.
However, on Windows at least, your second version works just fine.

I understand chomp to remove record separators from the end, is there
another reason besides?

Only that one. But it’s something you usually want to do.
Imagine your last line was
puts “I live in “+city+”, in a nice house.”
If you didn’t chomp, you’d get a newline right in the middle of your
sentence.
Also something like if (city == 'New York') would always fail
without the chomp.

  1. Is there a place I can go to learn more about regular expressions?

I keep going back to “Programming Ruby”, but there are probably better
choices.

  1. In IRB, Float::DIG => 15
    **question: This is because float displays to 15 decimals, right?

Float can hold up to 15 significant digits.
irb(main):053:0> f= 1+ 1e-14
=> 1.00000000000001

irb(main):054:0> f= 1+ 1e-15
=> 1.0 #can’t hold 16 digits.

irb(main):055:0> f=1+1e14
=> 1.00000000000001e+014

irb(main):056:0> f=1+1e15
=> 1.0e+015

**question: I see “::” all the time, but don’t understand it. What does
:: mean? Is it showing hierarchy?

It’s called the ‘scope operator’, it lets you Constants (including
other classes) declared inside the definition of the Class on the left
hand side.
If I have:
Class X
Z=0
Class Y;
# …
end
end

The only way to access Y or Z is with the X:: syntax.

n1 = NameIt.new(“tom”)
n2 = NameIt.new(“sally”)

n1.to_s
n2.to_s

**the last 4 lines seem very repetative. this is something I’ve wondered
for a long time. Is there a way to compact the last 4 lines if you are
trying to list a whole bunch of names at once using the method to_s?

Arrays and their iterator methods can be useful:

names = %w{ tom sally douglas} #shorthand for [“tom”,“sally”…]
nameits = names.map {|name| NameIt.new(name) }
nameits.each{|nit| puts n.to_s }

names.map calls the block for each entry in names, and returns
a new array of the same size, containg the results of the block.
nameits.each simply calls the block once for each entry.

hope this helps,
-Adam

I found some issues with the above proposed solutions that I wanted to
ask about:

class NameIt
def initialize(name)
@name = name
end
def to_s
puts “My name is: #{@name}”
end

def to_s
"My name is: " << name
# no puts
end

end

Clarifications/comments:

it appears that << name needs to be changed to << @name for it to work.
I assume this is because the scope of “name” is only known in the
initialize method and not the to_s method? I understand the scope of the
instance variable to be visible throughout the class. Is this the
reason?

Another question:

I entered this in:
class NameIt
def initialize(name)
@name = name
end
def to_s
puts "My name is: " << @name
end
end
names = %w( tom sally doug john)
nameits = names.map {|name| NameIt.new(name)}
nameits.each{|n| puts n.to_s}

and it returned this:

My name is: tom
nil
My name is: sally
nil
My name is: doug
nil
My name is: john
nil

Exit code: 0

Where did the nil come from?

Thanks! Jason

Thank you! Yes, very helpful.

the << operator is great:

And the map method is also great!

On Fri, May 16, 2008 at 1:38 PM, Jason L.
[email protected] wrote:

I assume this is because the scope of “name” is only known in the
initialize method and not the to_s method? I understand the scope of the
instance variable to be visible throughout the class. Is this the
reason?

Yep. You are correct. Sorry 'bout that.

Another question:

I entered this in:
class NameIt
def initialize(name)
@name = name
end
def to_s
puts "My name is: " << @name
end

Leave out the puts in #to_s. You want #to_s to return a string, not
execute a console output.

end
names = %w( tom sally doug john)
nameits = names.map {|name| NameIt.new(name)}
nameits.each{|n| puts n.to_s}

#puts calls #to_s, so you doing…

puts n.to_s

…is redundant. Just do…

puts n

hth,
Todd

Perfect. Thank you both!

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On May 16, 2008, at 8:38 PM, Jason L. wrote:

nameits.each{|n| puts n.to_s}
nil

Exit code: 0

Where did the nil come from?

To give you a more elaborate answer on why “nil” is printed… Lets
isolate that case:

===
def foo
puts “bar”
end

puts foo

This prints

bar
nil

Why? The Method #puts prints to standard out and returns nil. (in
Ruby 1.8.6, that will change in 1.9).

Every statement and method in Ruby has a return value. In the case of
Methods, the return value is eighter explicitly
stated or the value of the last statement in the method body. So the
#foo returns nil. As you call #puts again
on the return value of foo, you get the string representation of nil.
Which is… “nil”.

So you essentially wrote:

puts(puts(“bar”))

Regards,
Florian G.

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.8 (Darwin)

iEYEARECAAYFAkgt7iQACgkQJA/zY0IIRZZclwCfdm/QO25t7fQyj8gbWbgbeJBK
+lwAnA5EVgaQlGlD996qcme8eZY9h3xt
=wVhz
-----END PGP SIGNATURE-----