Forum: Ruby printing 2 dimensionl hash problem

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
C9030f7616a7da0dd3e7bf4987f46f07?d=identicon&s=25 Krekna Mektek (Guest)
on 2007-01-18 08:47
(Received via mailing list)
Hi,

busy with my script, I am trying to print my hash, which is built up as
follows:

hash:

key = A, value = [1,2,3]
key = B, value = [4,5,6]

etc.

I try this:

 @h.each do |key,value|
      print key, " is ", value.each {|x| print x, " -- " }, "\n"

The print is strange, becuase it looks like this now:

1 -- 2 -- 3 -- A is 123
4 -- 5 -- 6 -- B is 456

I don't understand why. If I interpreted this correctly, I've got the
following two questions:

1. How come the code block is executed first
2. After that the key and value is printed, however, I don't see the
print for the values here (except for the print in de the code block,
which was executed already).


Krekna
6087a044557d6b59ab52e7dd20f94da8?d=identicon&s=25 Peña, Botp (Guest)
on 2007-01-18 09:24
(Received via mailing list)
From: Krekna Mektek [mailto:krekna@gmail.com] :
#----------------------------------------------------------
#  @h.each do |key,value|
#       print key, " is ", value.each {|x| print x, " -- " }, "\n"
#
# The print is strange, becuase it looks like this now:
#
# 1 -- 2 -- 3 -- A is 123
# 4 -- 5 -- 6 -- B is 456
#
# 1. How come the code block is executed first
#----------------------------------------------------------

print expects to print a value of the expression (of course). so before
prints does the writing, it has to get the value first.

#----------------------------------------------------------
# 2. After that the key and value is printed, however, I don't see the
print for the values here (except for the print in de the code block,
which was executed already).
#----------------------------------------------------------

"value.each {...} " is an expression that returns a value, in this case
the array "value". that expression however will perform *first a {|x|
print x, "---"} for every element x in array "value".

eg,


C:\temp\rubygems-0.9.1>cat test.rb

h = {"A" => [1,2,3], "B" =>[4,5,6]}

puts "sample 1"
h.each do |key,value|
   print key, " is "
   value.each {|x| print x, " -- " }
   print "\n"
end
puts
puts "sample 2"
h.each do |key,value|
   puts "#{key} is #{value.join(' -- ')}"
end


C:\temp\rubygems-0.9.1>ruby test.rb
sample 1
A is 1 -- 2 -- 3 --
B is 4 -- 5 -- 6 --

sample 2
A is 1 -- 2 -- 3
B is 4 -- 5 -- 6

hth.
kind regards -botp
Ffcb418e17cac2873d611c2b8d8d891c?d=identicon&s=25 unknown (Guest)
on 2007-01-18 10:00
(Received via mailing list)
> etc.
>
> I don't understand why. If I interpreted this correctly, I've got the
> following two questions:
>
> 1. How come the code block is executed first
> 2. After that the key and value is printed, however, I don't see the
> print for the values here (except for the print in de the code block,
> which was executed already).

:) I think what you want to actually do is:

@h.each do |key,value|
  print key, " is ", value.join(' -- '), "\n"
end

or

@h.each do |key,value|
  puts key, " is ", value.join(' -- ')
end

To hopefully answer your questions:

You have asked Ruby to print out the return value of value.each{...},
which is simply value:

 [1,2,3] == [1,2,3].each {|n| do_something_with_n_if_you_like(n)}

So that explains the 123 at the end of the line, because [1,2,3].to_s is
"123"

Why the "1 -- 2 -- 3" before everything else though? Well, _before_ Ruby
can execute that first "print", it must _first_ evaluate what is being
printed, just as if you had writen "print 1+2+3". In calculating that,
Ruby calls values.each {...}, and this prints out the "1 -- 2 -- 3" at
the start of the line.

Hope that helps.
C9030f7616a7da0dd3e7bf4987f46f07?d=identicon&s=25 Krekna Mektek (Guest)
on 2007-01-18 11:50
(Received via mailing list)
2007/1/18, Peña, Botp <botp@delmonte-phil.com>:
> # 1. How come the code block is executed first
> #----------------------------------------------------------
>
> print expects to print a value of the expression (of course). so before prints does the 
writing, it has to get the value first.

>
> #----------------------------------------------------------
> # 2. After that the key and value is printed, however, I don't see the
> print for the values here (except for the print in de the code block,
> which was executed already).
> #----------------------------------------------------------
>
> "value.each {...} " is an expression that returns a value, in this case the array 
"value". that expression however will perform *first a {|x| print x, "---"} for every 
element x in array "value".
>

Thank you for your explanation!

I see now, that value.each is an argument to the print, which is not
what I need indeed, because like you said value.each with its code
block is already printing the values, so that's why they are printed
twice.

So, I've put the value.each on a separate line like in your example now.
Thus, the value.each expression is returned first, apparently the
arguments are parse before the (first) print is executed.

Same as this:
irb(main):012:0> print "I", " am ", "#{print "first "}"
first I am => nil


Krekna
C9030f7616a7da0dd3e7bf4987f46f07?d=identicon&s=25 Krekna Mektek (Guest)
on 2007-01-18 11:53
(Received via mailing list)
Thank you very much, my answer was posted before I read this.
I think it's clear to me now.
That's the best way, learning by doing and talking about it what
actually happens when something went wrong.

Thank you too.

Krekna

2007/1/18, benjohn@fysh.org <benjohn@fysh.org>:
This topic is locked and can not be replied to.