Iterate hash to make another hash

string. The result is a hash because the string contains “ => “?

The result is a hash because hash.each is called for its side effects and
returns self. Nothing more.

Try to write a program that gives you different results for a and b in

hash = { ... }
a = hash.each {|k, v| "#{k} => #{v}"}
b = hash.each {|k, v| 42}

fill whatever combination of strings, symbols, etc. you like into hash.

Also check out the object_id method.

martin

···

On Oct 2, 2016 11:25 AM, "Bee.Lists" <bee.lists@gmail.com> wrote:

A join on two symbols and an object which, in this case, was decidedly a

You forgot what is important here. The join. The result of a join is not a hash.

Cheers, Bee

···

On Oct 2, 2016, at 2:50 PM, Martin DeMello <martindemello@gmail.com> wrote:

The result is a hash because hash.each is called for its side effects and returns self. Nothing more.

Try to write a program that gives you different results for a and b in

hash = { ... }
a = hash.each {|k, v| "#{k} => #{v}"}
b = hash.each {|k, v| 42}

fill whatever combination of strings, symbols, etc. you like into hash.

Also check out the object_id method.

This is wrong.

1. Documentation:

2. Experiments:

irb(main):001:0> a = [1, "foo", :bar, Object.new]
=> [1, "foo", :bar, #<Object:0x00000001f16f20>]
irb(main):002:0> a.each {|x| a.each {|y| printf "Test: %p, %p\n", x,
y; r = [x,y].join("@"); printf "Result: %p, %s\n", r, r.class}}
Test: 1, 1
Result: "1@1", String
Test: 1, "foo"
Result: "1@foo", String
Test: 1, :bar
Result: "1@bar", String
Test: 1, #<Object:0x00000001f16f20>
Result: "1@#<Object:0x00000001f16f20>", String
Test: "foo", 1
Result: "foo@1", String
Test: "foo", "foo"
Result: "foo@foo", String
Test: "foo", :bar
Result: "foo@bar", String
Test: "foo", #<Object:0x00000001f16f20>
Result: "foo@#<Object:0x00000001f16f20>", String
Test: :bar, 1
Result: "bar@1", String
Test: :bar, "foo"
Result: "bar@foo", String
Test: :bar, :bar
Result: "bar@bar", String
Test: :bar, #<Object:0x00000001f16f20>
Result: "bar@#<Object:0x00000001f16f20>", String
Test: #<Object:0x00000001f16f20>, 1
Result: "#<Object:0x00000001f16f20>@1", String
Test: #<Object:0x00000001f16f20>, "foo"
Result: "#<Object:0x00000001f16f20>@foo", String
Test: #<Object:0x00000001f16f20>, :bar
Result: "#<Object:0x00000001f16f20>@bar", String
Test: #<Object:0x00000001f16f20>, #<Object:0x00000001f16f20>
Result: "#<Object:0x00000001f16f20>@#<Object:0x00000001f16f20>", String
=> [1, "foo", :bar, #<Object:0x00000001f16f20>]

robert

···

On Sun, Oct 2, 2016 at 8:24 PM, Bee.Lists <bee.lists@gmail.com> wrote:

Two strings or symbols, joined with a string, returns a hash, and I said it was interesting and useful.

--
[guy, jim, charlie].each {|him| remember.him do |as, often| as.you_can
- without end}
http://blog.rubybestpractices.com/

Just to be absolutely clear once again, this is the exact code we're
talking about:

···

~~~
t.each {|k,v| puts [k,v].join(" => ")}
~~~

If we unwrap it a bit it looks like this:

~~~
t.each do |k, v|
  kv_string = [k,v].join(" => ")
  puts kv_string
end
~~~

I hope that's uncontroversial.

On 3 October 2016 at 04:24, Bee.Lists <bee.lists@gmail.com> wrote:

> On Oct 1, 2016, at 8:15 PM, Matthew Kerwin <matthew@kerwin.net.au> > wrote:
>
>
>
> On 2 October 2016 at 09:19, Bee.Lists <bee.lists@gmail.com> wrote:
> There is no print in any of this. Second, asking a hash for a key or a
value both return a string. String plus string plus string, should result
in a string, as per documentation.
>
>
> ​http://ruby-doc.org/core-2.3.0/Kernel.html#method-i-puts which leads
to Class: IO (Ruby 2.3.0) which says:
"Writes the given objects to ios as with IO#print."
>
> Asking a hash for a key or a value both return whatever object is used
in the hash's key or value. If those are Strings, then it returns Strings.

A join on two symbols and an object which, in this case, was decidedly a
string. The result is a hash because the string contains “ => “?

> ~~~
> hsh = { 0 => 3.14, :foo => Object.new }
> hsh[0].class #=> Float
> hsh.keys[1].class #=> Symbol
>
> # and finally
> hsh.each{nil} == hsh #=> true
> ~~~
>
> ​Yes, joining two Strings with a String results in a String... which is
then printed using `puts`. It's not returned in any way. I know I've said
this already, and I assume you've understood even though you haven't
acknowledged it (which is why I've repeated it again here.) I just want to
make sure the original issue is resolved and clear.

The puts has nothing to do with any of this. You can repeat it until next
week, but it has absolutely nothing to do with any of this. Nothing. I’ll
repeat myself: nothing. The original issue is not what was presented via
the puts (or print, as somebody else said, which was never part of any
discussion…but we move on). It was about the result through the join.

Let me repeat the important bits, then, since you're hung up on the
puts/print:

*Joining two Strings with a String results in a String.*

As the puts is unimportant, we can reduce the unwrapped code to this:

~~~
t.each do |k, v|
  kv_string = [k,v].join(" => ")
end
~~~

*It is not returned in any way.*

Since this is Ruby and everything is an expression, the return value from
the do-end block each time it is invoked is the kv_string. However
Hash#each completely ignores the value returned from its block. Since
Array#join has no side-effects aside from its return value, this code is
functionally equivalent to this:

~~~
t.each do |k, v|
end
~~~

which is functionally equivalent to this:

~~~
t
~~~

This is also uncontroversial, well documented, and testable.

So: the thing that returns a Hash is not Array#join, but is, in fact,
Hash#each. But it doesn't return a *new* Hash; it returns the original
receiving Hash object, unmodified.

> > I’ve been doing stuff like that since the 80’s.
>
> I'm glad you've been programming since I was a wee babby. I've only been
doing it since the 90s (Ruby for about a decade.) That's not relevant,
though.

Well, you see, it is. First, you just brought it up. Second, don’t
assume that everybody else is beneath you.

> > Also Matthew, don’t assume I didn’t read the notes on this.
>
> The documentation for Hash#each shows, somewhat abstractly perhaps but
consistent with the official Ruby docs idioms, that it returns the receiver
unmodified. Hence my request that you read (with emphasis) the
documentation. (And they're not notes, they're the official human-readable
contract for how the core libraries' APIs behave.)

Class: Hash (Ruby 2.3.1)

Class: Hash (Ruby 2.3.1)

> The resulting object passes the `.class == Hash` test, but a deeper
inspection would have shown that the result comes out unmodified by `each`;
for example: `p( t.each {|k,v| puts [​v, k].join(" => ")}​ )​​` would have
shown that the final result is identical to `t`, even though I flipped the
`k` and `v` inside the loop. Hence my request that you formulate meaningful
ways to test hypotheses. Testing a noop that, even if it did something
would still end up being a noop, is not very useful. Also note that
`[p,k].join("=>")` removes all the quotation marks that would have made it
parseable as a Hash of Strings.

So you’re saying they don’t have a data type. Right. That makes no sense
at all.

​I agree, that's absurd, and therefore it should be assumed that that's in
fact not what I'm saying. Allow me to break it down.

If this is a String:

~~~
"hello world"
~~~

And this is a String that looks like it contains a valid Ruby value:

~~~
"[123, \"foo\"]"
~~~​

Then, by comparison, this is a String that does *not* look like it contains
valid Ruby values:

~~~
"foo => bar"
~~~

That is what I was saying. There are no quotation marks *inside the string*,
therefore it is not parseable as a Hash of Strings. So even if some voodoo
magic was evaluating the String returned by Array#join, it doesn't look
like valid Ruby code so it wouldn't evaluate anyway.

> Please don't take my advice as admonishment (unless you've a guilty
conscience, and even then...) and certainly don't dismiss me because of
your life experiences -- fine whisky improves with age, but in the tech
world it's far more common for the synonym of "old" to be "obsolete."
Asking for advice on these mailing lists is a great thing; accepting the
advice is the hard part.

Please don’t take my correction as an indication you are wrong. Older
people are the ones you received any education from. Second, your “advice”
holds no water, considering the case. Two strings or symbols, joined with
a string, returns a hash, and I said it was interesting and useful. You
insist on talking about the puts, which is completely irrelevant, but you
feel the need to repeat yourself.

​I wasn't educated by older people, I was educated by wiser people. One
can't accumulate wisdom without age, but one can accumulate age without
wisdom.

My "advice" only holds no water if you don't understand it.

Two Strings or Symbols, joined with a String, returns a String. It doesn't
matter if you call #join out of the blue, or inside Hash#each, or anywhere
else: `[str1,str2].join(" => ")` returns a String. Always. Without
exception. This is clearly documented
Class: Array (Ruby 2.3.1) and trivial to
test, if only you would *read *the documentation for the functions you're
using, *read *the code, formulate *meaningful *ways to test your
hypotheses, and listen to the advice given to you by the people from whom
you sought it. (Sounds familiar.)

The thing I feel the need to repeat, even now having stated it several
times because clearly it hasn't sunk in, is: if you don't use the value
returned by a function that has no other side-effects, that function is a
noop. It does nothing. Hash#each does nothing if you don't somehow use the
values you construct inside it. Which is not happening in this case.

See? I said it this time without mentioning the 'p' word.​

Have a nice day.

Cheers, Bee

--
  Matthew Kerwin
  http://matthew.kerwin.net.au/

Hi!

Indeed, you're right, the result of the join is not a hash, entirely true.
But the result of the join is discarded. each does not return the result of
its inside block, it's not how this method works.
If you want that to happen, use map.

$ irb
irb(main):001:0> t = { 'pony' => 'unicorn', 42 => 24 }
=> {"pony"=>"unicorn", 42=>24}
irb(main):002:0> t.each { |k, v| [k, v].join(' => ') }
=> {"pony"=>"unicorn", 42=>24}
irb(main):003:0> t.map { |k, v| [v, k].join(' => ') }
=> ["unicorn => pony", "24 => 42"]

As you can see here, the result of ["lol", "rofl"].join(" whatever ") gives
"lol whatever rofl".

Best,
Thomas.

···

On Sun, Oct 2, 2016 at 9:56 PM Bee.Lists <bee.lists@gmail.com> wrote:

> On Oct 2, 2016, at 2:50 PM, Martin DeMello <martindemello@gmail.com> > wrote:
>
> The result is a hash because hash.each is called for its side effects
and returns self. Nothing more.
>
> Try to write a program that gives you different results for a and b in
>
> hash = { ... }
> a = hash.each {|k, v| "#{k} => #{v}"}
> b = hash.each {|k, v| 42}
>
> fill whatever combination of strings, symbols, etc. you like into hash.
>
> Also check out the object_id method.

You forgot what is important here. The join. The result of a join is not
a hash.

Cheers, Bee

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;

Fill whatever code you like into the block too.

martin

···

On Sun, Oct 2, 2016 at 12:56 PM, Bee.Lists <bee.lists@gmail.com> wrote:

> On Oct 2, 2016, at 2:50 PM, Martin DeMello <martindemello@gmail.com> > wrote:
>
> The result is a hash because hash.each is called for its side effects
and returns self. Nothing more.
>
> Try to write a program that gives you different results for a and b in
>
> hash = { ... }
> a = hash.each {|k, v| "#{k} => #{v}"}
> b = hash.each {|k, v| 42}
>
> fill whatever combination of strings, symbols, etc. you like into hash.
>
> Also check out the object_id method.

You forgot what is important here. The join. The result of a join is not
a hash.

​And if anyone's interested, the relevant Ruby source code is on github:
https://github.com/ruby/ruby/blob/trunk/array.c#L1945-L2093 Particularly
note line 1973 which appends the separator, and line 1974 which appends the
next String object, if #join is called on an Array of Strings.

Cheers

···

On 3 October 2016 at 07:24, Matthew Kerwin <matthew@kerwin.net.au> wrote:

Two Strings or Symbols, joined with a String, returns a String. It doesn't
matter if you call #join out of the blue, or inside Hash#each, or anywhere
else: `[str1,str2].join(" => ")` returns a String. Always. Without
exception.

--
  Matthew Kerwin
  http://matthew.kerwin.net.au/

Hi
I'm surprised - 27 messages, the maximum for one help-topic in the whole
year...
Nobody whispering "a troll?" or even noob/... -- ok, the mailing-list has
evolved, which is positive.

Maybe I feel a little aggrieved, such detailed answers, repeated soooo many
times, and then no answer or something like "thank you folks".

Why dont I get these many replies?
The more difficult the question, the less answers?
What am I doing wrong?

Bye
Berg