Strange behaviour

J

Javier Valencia

Look this:

tigre@enigma tigre $ irb
irb(main):001:0> events = {}
=> {}
irb(main):002:0> events.default = []
=> []
irb(main):003:0> events["trying"] << "hello"
=> ["hello"]
irb(main):004:0> events
=> {}
irb(main):005:0> events.inspect
=> "{}"
irb(main):006:0> events["trying"]
=> ["hello"]
irb(main):007:0> quit
tigre@enigma tigre $


why is happening this behaviour?
 
J

Jacob Fugal

tigre@enigma tigre $ irb
irb(main):001:0> events =3D {}
=3D> {}
irb(main):002:0> events.default =3D []
=3D> []
irb(main):003:0> events["trying"] << "hello"
=3D> ["hello"]
irb(main):004:0> events
=3D> {}
irb(main):005:0> events.inspect
=3D> "{}"
irb(main):006:0> events["trying"]
=3D> ["hello"]
irb(main):007:0> quit
tigre@enigma tigre $


why is happening this behaviour?

Take a look at this for some clues:

$ irb
irb(main):001:0> events =3D {}
=3D> {}
irb(main):002:0> events.default =3D []
=3D> []
irb(main):003:0> events["trying"] << "hello"
=3D> ["hello"]
irb(main):004:0> events.default
=3D> ["hello"]
irb(main):005:0> events["test"]
=3D> ["hello"]

In short, what's happening is that when you call events["trying"] at
statement 3, it returns the default value, which is an array. You then
insert "hello" into that array and *change the default value*. Since
you never assigned to events["trying"], it still doesn't exist. You
were only getting the expected value back on re-access because of the
changed default value.

Try this instead:

$ irb
irb(main):001:0> events =3D Hash.new{ |h,k| h[k] =3D [] }
=3D> {}
irb(main):002:0> events.default
=3D> []
irb(main):003:0> events["trying"] << "hello"
=3D> ["hello"]
irb(main):004:0> events.default
=3D> []
irb(main):005:0> events["trying"]
=3D> ["hello"]
irb(main):006:0> events["test"]
=3D> []
irb(main):007:0> events
=3D> {nil=3D>[], "test"=3D>[], "trying"=3D>["hello"]}

This produces the desired behavior, but you have to be careful, since
accessing non-existent keys will pollute the keys of your hash.
 
G

Gregory Seidman

This stems from a fundamental misunderstanding of how the default
attribute of a hash is used by the hash.

}
} tigre@enigma tigre $ irb
} irb(main):001:0> events = {}
} => {}

The events variable has been set to a new instance of a hash.

} irb(main):002:0> events.default = []
} => []

The events.default attribute has been set to a new instance of an array.

} irb(main):003:0> events["trying"] << "hello"
} => ["hello"]

The array in the events.default attribute is retrieved, since "trying" is
not a key in the hash, and has "hello" appended to it.

} irb(main):004:0> events
} => {}

The events variable continues to hold an empty hash, which has a default
attribute set to ["hello"].

} irb(main):005:0> events.inspect
} => "{}"

Still empty.

} irb(main):006:0> events["trying"]
} => ["hello"]

The events.default attribute is retrieved since "trying" is not a key in
the hash. The attribute is an array which has previously had "hello"
appended to it.

} why is happening this behaviour?

This is correct behavior. The default attribute is not the default starting
value for any key, it is the value returned when a key is not found. See
the following:

irb(main):001:0> events = {}
=> {}
irb(main):002:0> events.default = []
=> []
irb(main):003:0> events["trying"] << "hello"
=> ["hello"]
irb(main):004:0> events["nosuchkey"]
=> ["hello"]
irb(main):005:0> events.default
=> ["hello"]
irb(main):006:0> events.default.object_id
=> 403034172
irb(main):007:0> events["trying"].object_id
=> 403034172
irb(main):008:0> events["nosuchkey"].object_id
=> 403034172
 

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
473,968
Messages
2,570,153
Members
46,701
Latest member
XavierQ83

Latest Threads

Top