newbee question about "missing" hash methods +, += and <<

B

benny

Hi,

I'm wondering if there is a special reason for the class Hash not to have the methods +, += and <<
just like Array. I would find it intuitive if I could do something like this

testhash = Hash.new
testhash << {"some key" => "some value"}

or even

secondhash = {"some other key" => "some other value"}
testhash += secondhash
#-> {"some key" => "some value", "some other key" => "some other value"}

thats the behaviour of arrays and I know that I could extend the class Hash, so that its supported.
I simply want to know if there is a special reason why it is not supported by default.

benny
 
T

ts

b> thats the behaviour of arrays and I know that I could extend the class
b> Hash, so that its supported. I simply want to know if there is a special
b> reason why it is not supported by default.

What do you do if the key exist ?

Array#+ always add elements, with Hash#+ keys will be added only if the
key don't exist otherwise the old value is replaced.



Guy Decoux
 
H

Hal Fulton

ts said:
b> thats the behaviour of arrays and I know that I could extend the class
b> Hash, so that its supported. I simply want to know if there is a special
b> reason why it is not supported by default.

What do you do if the key exist ?

Array#+ always add elements, with Hash#+ keys will be added only if the
key don't exist otherwise the old value is replaced.

I have seen this discussion before.

It doesn't bother me much that keys are replaced. That is the nature of
a Hash, that keys are unique.

What bothers me more: If h2 and h3 have common keys, then
h1 = h2 + h3
is not the same as
h1 = h3 + h2

In other words, I expect + to be commutative always. But probably
someone will now show me a case where it is not in Ruby. :)


Hal
 
T

ts

H> In other words, I expect + to be commutative always. But probably
H> someone will now show me a case where it is not in Ruby. :)

ruby -e 'p [1]+[2]==[2]+[1]'


Guy Decoux
 
R

Robert Klemme

benny said:
Hi,

I'm wondering if there is a special reason for the class Hash not to have the methods +, += and <<
just like Array.

First of all, no class has a method "+=". Instead this is a syntactic
shortcut that transforms "a += b" into "a = a + b" - whatever 'a' and 'b'
are.
I would find it intuitive if I could do something like this

testhash = Hash.new
testhash << {"some key" => "some value"}

There is "update":

irb(main):004:0> testhash = {}
=> {}
irb(main):005:0> testhash.update( {"some key" => "some value"} )
=> {"some key"=>"some value"}
irb(main):006:0> testhash
=> {"some key"=>"some value"}
secondhash = {"some other key" => "some other value"}
testhash += secondhash
#-> {"some key" => "some value", "some other key" => "some other
value"}

irb(main):007:0> secondhash = {"some other key" => "some other value"}
=> {"some other key"=>"some other value"}
irb(main):008:0> testhash.update secondhash
=> {"some other key"=>"some other value", "some key"=>"some value"}
thats the behaviour of arrays and I know that I could extend the class Hash, so that its supported.
I simply want to know if there is a special reason why it is not
supported by default.

I guess it's that Hash#update is peculiar because it depends on which hash
is updated by the other, which is important if both Hashes share some
keys. Apart from that Hash#+ might be a bit inefficient in situations
where you want to update a Hash via +=.

class Hash
def +(h)
dup.update(h)
end
end

a = {}
b = {}

a += b

# in reality:
# tmp = a + b
# a = tmp
# old a is dropped

Kind regards

robert
 
B

benny

First of all, no class has a method "+=". Instead this is a syntactic
shortcut that transforms "a += b" into "a = a + b" - whatever 'a' and 'b'
are.
ok


There is "update":

yes, I know, but I thought about syntactic consistency
perhaps I have an interation about differenz objects, some of them are arrays, some are hashs (and I
don't want to check it all the time)
I guess it's that Hash#update is peculiar because it depends on which hash
is updated by the other, which is important if both Hashes share some
keys.

but its quite clear: the right hash replaces the entry in the left hash with the same key, just
like update. why inventing a new method name for basically same thing?
Apart from that Hash#+ might be a bit inefficient in situations
where you want to update a Hash via +=.

thats the samething with

teststring = "hello"
teststring += " boys and girls"

vs

teststring << "boys and girls"

so why not having "<<" (without temporary object) and "+" or "+=" (with temporary object) instead of
"update"?

I'm not convinced yet.
 
B

benny

Am Wed, 28 Jan 2004 01:39:01 +0900
schrieb ts said:
H> In other words, I expect + to be commutative always. But probably
H> someone will now show me a case where it is not in Ruby. :)

ruby -e 'p [1]+[2]==[2]+[1]'


Guy Decoux

conclusion: no argument against "<<" / "+" for hashs?
and "delete" is even more obscure when we have "-" : e.g.

testhash = {"key" => "value", "other key" => "other entry"}
otherhash = {"other key" => "other entry"}

testhash - "key" #-> {"other key" => "other entry"}

# should delete the entry with the key "key"

testhash - otherhash #-> {}

# should delete the corresponding entry as well

I think this is far more intuitive and flexible
 
H

Hal Fulton

ts said:
H> In other words, I expect + to be commutative always. But probably
H> someone will now show me a case where it is not in Ruby. :)

ruby -e 'p [1]+[2]==[2]+[1]'

Yes, yes. :) But at least they have the same contents.

Merci beaucoups, M'sieur Decoux.

Hal
 
T

ts

b> conclusion: no argument against "<<" / "+" for hashs?

Well, it's more : no arguments for Hash#<< and Hash#+

moulon% ruby -e 'p "aa"<<"bb"'
"aabb"
moulon%

moulon% ruby -e 'p ["aa"]<<"bb"'
["aa", "bb"]
moulon%

Now try the same with an Hash (order is given by the hash value, and not
by the last element added)


Guy Decoux
 
R

Robert Klemme

benny said:
Am Wed, 28 Jan 2004 01:39:01 +0900
schrieb ts said:
"H" == Hal Fulton <[email protected]> writes:

H> In other words, I expect + to be commutative always. But probably
H> someone will now show me a case where it is not in Ruby. :)

ruby -e 'p [1]+[2]==[2]+[1]'


Guy Decoux

conclusion: no argument against "<<" / "+" for hashs?

No. Arguments are:

"+" is inefficient. (same for "-")

"<<" has usually the semantics that the left side is a collection while
the right side is an element. And since each entry in a Hash needs a key
value pair this could not be done with <<, because "<<" can only have a
single argument. You could only implement << in a way that "h << [key,
value]" would add the pair (key, value), but this is by no means clearer
than "h[key] = value" IMHO.

see Array: [1]<<[2] yields [1,[2]] and not [1,2]
and "delete" is even more obscure when we have "-" : e.g.

testhash = {"key" => "value", "other key" => "other entry"}
otherhash = {"other key" => "other entry"}

Again, this is not symmetric with other occurences of "-": left and right
side should be of the same type, at least both should be containers, i.e.
hashes in this case.
testhash - "key" #-> {"other key" => "other entry"}

# should delete the entry with the key "key"

testhash - otherhash #-> {}

# should delete the corresponding entry as well

What should it do if the Hash contains Hashes as keys? This is highly
ambiguous and not intuitive.
I think this is far more intuitive and flexible

Regards

robert
 
B

benny

Am Wed, 28 Jan 2004 02:22:05 +0900
schrieb ts said:
b> conclusion: no argument against "<<" / "+" for hashs?

Well, it's more : no arguments for Hash#<< and Hash#+

moulon% ruby -e 'p "aa"<<"bb"'
"aabb"
moulon%

moulon% ruby -e 'p ["aa"]<<"bb"'
["aa", "bb"]
moulon%

Now try the same with an Hash (order is given by the hash value, and not
by the last element added)
I read somewhere that the result of the "shift" method is unpredictable because there is no fixed
order in hashes so it shouldn't matter IMHO. or did I get you wrong?

{"a" => "b"} << {"c" => "d"} #-> {"a" => "b", "c" => "d"}
 
T

ts

b> I read somewhere that the result of the "shift" method is unpredictable
b> because there is no fixed order in hashes so it shouldn't matter
b> IMHO. or did I get you wrong?

and I hope that you have read that it don't exist a method
Hash#unshift :)


Guy Decoux
 
B

benny

No. Arguments are:

"+" is inefficient. (same for "-")

dito with
"string" += "other_string"
but ok, we can skip this
"<<" has usually the semantics that the left side is a collection while
the right side is an element. And since each entry in a Hash needs a key
value pair this could not be done with <<, because "<<" can only have a
single argument.


what about

"a" << "bcd"

or

["a"] << ["b", ["c", "d"], "e"]
?

You could only implement << in a way that "h << [key,
value]" would add the pair (key, value), but this is by no means clearer
than "h[key] = value" IMHO.

- you can iterate above hashs and arrays without taking care if they are hashs or arrays.
- you only have to learn one syntax
- ....


see Array: [1]<<[2] yields [1,[2]] and not [1,2]
but 'a' << "bcd" yields 'abcd' and not 'a"bcd"'

so thats special to the array-class. but it should neccessarily affect hashes.

1 << 3 #-> 8
thats special to the Fixnum class so you have to learn that behaviour anyway

Again, this is not symmetric with other occurences of "-": left and right
side should be of the same type, at least both should be containers, i.e.
hashes in this case.

I could agree with that. just thought that the second way would be useful (-> delete)
What should it do if the Hash contains Hashes as keys? This is highly
ambiguous and not intuitive.

no, its quite clear: it happens the same thing like

myhash[{"key" => "val"}] = "other_val"

benny
 
B

benny

X-Newsreader: Sylpheed version 0.9.8claws (GTK+ 1.2.10; i386-portbld-freebsd4.9)
Mime-Version: 1.0
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

Am Wed, 28 Jan 2004 02:45:51 +0900
schrieb ts said:
=20
b> I read somewhere that the result of the "shift" method is unpredictable
b> because there is no fixed order in hashes so it shouldn't matter
b> IMHO. or did I get you wrong?=20
=20
and I hope that you have read that it don't exist a method=20
Hash#unshift :)
=20
=20

it was a german book:

"Programmieren mit Ruby" [Programing with ruby]
Armin R=F6hrl, Stefan Schmiedl, Clemens Wyss
Heidelberg 2002, ISBN 3-89864-151-1

page 47
[translated into my bad english]

Because hashes don't have a fixed order the result of this method is unpred=
ictable. "delete" on the
other hand permits the deletition of an element with a known key.

I know "unshift" only from php. what do you want to tell me with this state=
ment?
should I better stay programing php?

benny
 
H

Hal Fulton

benny said:
I know "unshift" only from php. what do you want to tell me with this state=
ment?
should I better stay programing php?

Notice there is a smiley. Apparently a small joke.

I guess when you said "shift" you meant << (which looks like
the numeric shift operator) rather than the actual method
named shift (whose opposite is unshift).

I think this minor misunderstanding is only the result of
a French person and a German person conversing in English.


Cheers,
Hal
 
B

benny

Am Wed, 28 Jan 2004 03:45:35 +0900
schrieb Hal Fulton said:
Notice there is a smiley. Apparently a small joke.

I guess when you said "shift" you meant << (which looks like
the numeric shift operator) rather than the actual method
named shift (whose opposite is unshift).

no I meant the method "shift" and indeed there is no method "unshift" for hashes (in ruby, in php,
there is).

I refered to the method "shift" because Mr. Decoux stated
"(order is given by the hash value, and not
by the last element added)"

to say that you can't use << for hashes.

I'm not shure if I got him right. I thought he said

"the order of the new element in the array when using ["a"] << "b" is given by the array , so that
the added element is always the last one. how would that be in a hash, where we have a key?"

and I wanted to tell him

"I always thought the order doesn't matter in a hash as you can see be the unpredictability of the
result of the method shift."
I think this minor misunderstanding is only the result of
a French person and a German person conversing in English.

I think its more the aim of minimalistic communication that leads to confusion.

nevertheless my proposal wasn't {"a" => "b"} << "c => d" (analog to ["a"] << "b" ) but
{"a" => "b"} << {"c" => "d"}

(see my other posting).

and the argument that this would mean another thing than with arrays (adding an association instead
of an element) I think is not so important because, Hash is an other Object than Array and can
handle << in its own useful way (as String and Fixnum also do).
Cheers,
Hal
ps. I saw the smiley just wanted to know if I interpreted the allusion "unshift" the right way.

cheers,

benny
 
H

Hal Fulton

benny said:
and the argument that this would mean another thing than with arrays (adding an association instead
of an element) I think is not so important because, Hash is an other Object than Array and can
handle << in its own useful way (as String and Fixnum also do).

Hmm. I suppose I can see both sides of this.
ps. I saw the smiley just wanted to know if I interpreted the allusion "unshift" the right way.

OK. Anyway I am sure he was not telling you to leave Ruby
and go back to PHP.

Your English is good, by the way. I had the chance to use my (minimal)
German back in June at the European conference. Fortunately everyone
spoke English, because I would have run out of vocabulary in less than
twenty minutes. :)

Hal
 
D

Dan Doel

benny said:
nevertheless my proposal wasn't {"a" => "b"} << "c => d" (analog to ["a"] << "b" ) but
{"a" => "b"} << {"c" => "d"}
You can do this yourself:

class Hash
alias_method :<<, :update
end

- Dan
 
B

benny

Am Wed, 28 Jan 2004 05:15:23 +0900
schrieb Dan Doel said:
benny said:
nevertheless my proposal wasn't {"a" => "b"} << "c => d" (analog to ["a"] << "b" ) but
{"a" => "b"} << {"c" => "d"}
You can do this yourself:

class Hash
alias_method :<<, :update
end

- Dan

yes, I know. it was only a suggestion to put it in the base syntax / a question why it is not in
there.

but thanx anyway :)

benny
 
R

Robert Klemme

benny said:
dito with
"string" += "other_string"
Yes.


what about

"a" << "bcd"

True. String is special with respect to <<.
What should it do if the Hash contains Hashes as keys? This is highly
ambiguous and not intuitive.

no, its quite clear: it happens the same thing like

myhash[{"key" => "val"}] = "other_val"

No, we were talking about "-": If h is a Hash that contains hashes as
keys like h = { {"foo"=>"bar"} =>1 } then how is "h - x" interpreted if x
is a Hash? It's ambiguous.

Regards

robert
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,141
Messages
2,570,818
Members
47,367
Latest member
mahdiharooniir

Latest Threads

Top