being very confused about this hash

Discussion in 'Ruby' started by Ruby Newbee, Jan 6, 2010.

  1. Ruby Newbee

    Ruby Newbee Guest

    Hi,

    irb(main):039:0> hash = Hash.new []
    => {}
    irb(main):040:0> hash['abc'] << 3
    => [3]
    irb(main):041:0> hash.keys
    => []
    irb(main):042:0> hash['def']
    => [3]


    Since I have created a key/value pair with hash['abc'] << 3, why
    hash.keys show nothing?
    And, why hash['abc'] << 3 changed the hash's default value (which
    should be an empty array)?

    Thanks.
     
    Ruby Newbee, Jan 6, 2010
    #1
    1. Advertising

  2. Ruby Newbee

    Bill Kelly Guest

    Ruby Newbee wrote:
    >
    > irb(main):039:0> hash = Hash.new []
    > => {}
    > irb(main):040:0> hash['abc'] << 3
    > => [3]
    > irb(main):041:0> hash.keys
    > => []
    > irb(main):042:0> hash['def']
    > => [3]
    >
    >
    > Since I have created a key/value pair with hash['abc'] << 3, why
    > hash.keys show nothing?
    > And, why hash['abc'] << 3 changed the hash's default value (which
    > should be an empty array)?


    I'm not sure why hash.keys was empty.

    But with regard to the default value, we are providing an
    object (a specific instance of the Array class) to be used
    as the default.

    We can illustrate this by asking Ruby to show us the object_id
    of the default object:

    irb(main):001:0> ary = []
    => []
    irb(main):002:0> ary.object_id
    => 20919800
    irb(main):003:0> h = Hash.new ary
    => {}
    irb(main):004:0> h['foo'].object_id
    => 20919800
    irb(main):005:0> h['bar'].object_id
    => 20919800

    So we can see the object_id of the default object is indeed
    the same object_id of the array we provided to Hash.new.

    * * *

    We can instead provide a block to Hash.new which allows us
    to create a _new_ unique object (instance of Array) whenever
    a new default value is needed:

    irb(main):001:0> h = Hash.new {|h,k| h[k] = []}
    => {}
    irb(main):002:0> h['abc'] << 3
    => [3]
    irb(main):003:0> h.keys
    => ["abc"]
    irb(main):004:0> h['def']
    => []


    Regards,

    Bill
     
    Bill Kelly, Jan 6, 2010
    #2
    1. Advertising

  3. On Tuesday 05 January 2010 09:39:53 pm Ruby Newbee wrote:
    > irb(main):039:0> hash = Hash.new []


    I assume here that [] is the default value, right?
    > => {}
    > irb(main):040:0> hash['abc'] << 3
    > => [3]
    > irb(main):041:0> hash.keys
    > => []
    > irb(main):042:0> hash['def']
    > => [3]
    >
    >
    > Since I have created a key/value pair with hash['abc'] << 3, why
    > hash.keys show nothing?


    Because you haven't set anything in the hash. That is,

    hash['abc'] = 3

    is equivalent to:

    hash.[]=('abc', 3)

    On the other hand, what you've done is:

    hash['abc'] << 3

    That's equivalent to:

    hash.[]('abc') << 3

    I don't know if that helps, but that's the difference. Let me put it this way
    -- suppose you hadn't changed the default value:

    irb(main):001:0> hash = {}
    => {}
    irb(main):002:0> hash['abc']
    => nil
    irb(main):003:0> hash.keys
    => []

    Do you understand why that works the way it does? But there's nothing special
    about nil here, it's just the, erm, _default_ default value -- it's what Hash
    uses as a default value if you don't specify one.

    > And, why hash['abc'] << 3 changed the hash's default value (which
    > should be an empty array)?


    Because you set the default value to [], which creates an empty array object,
    once. The hash is just assigning it each time. Think of it this way:

    irb(main):004:0> default = []
    => []
    irb(main):005:0> a = default
    => []
    irb(main):006:0> b = default
    => []
    irb(main):007:0> a << 3
    => [3]
    irb(main):008:0> b
    => [3]

    What you really want is the block notation of creating a hash, which lets you
    actually specify some code that's run to create a default value, as Bill Kelly
    says. The reason his code works is that when you try to access a value that
    doesn't exist, it actually runs some code which sets that value:

    h = Hash.new {|h,k| h[k] = []}

    It wouldn't work at all if you just did this:

    h = Hash.new {|h,k| []}

    That would at least give you a new array each time, but since it wouldn't set
    it, you'd see weird things:

    irb(main):010:0> h['abc'] << 3
    => [3]
    irb(main):011:0> h['abc']
    => []
    irb(main):012:0> h.keys
    => []
     
    David Masover, Jan 6, 2010
    #3
  4. Ruby Newbee

    Ruby Newbee Guest

    On Wed, Jan 6, 2010 at 1:52 PM, David Masover <> wrote:
    > On Tuesday 05 January 2010 09:39:53 pm Ruby Newbee wrote:
    >> Since I have created a key/value pair with hash['abc'] << 3, why
    >> hash.keys show nothing?

    >
    > Because you haven't set anything in the hash. That is,
    >
    > hash['abc'] = 3
    >
    > is equivalent to:
    >
    > hash.[]=('abc', 3)
    >
    > On the other hand, what you've done is:
    >
    > hash['abc'] << 3
    >
    > That's equivalent to:
    >
    > hash.[]('abc') << 3
    >



    Thanks for the explaining, now I think I have got it.
    I'm always thinking it as the Perl way, since in Perl the syntax like
    hash['abc'] << 3 will create a key/value pairs.

    perl -MData::Dumper -le '$hash={}; push @{$hash->{'abc'}},3; print Dumper $hash'
    $VAR1 = {
    'abc' => [
    3
    ]
    };


    I didn't know in Ruby hash['abc'] = 3 and hash['abc'] << 3 are different.
    Thanks again.
     
    Ruby Newbee, Jan 6, 2010
    #4
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Raymond Arthur St. Marie II of III

    very Very VERY dumb Question About The new Set( ) 's

    Raymond Arthur St. Marie II of III, Jul 23, 2003, in forum: Python
    Replies:
    4
    Views:
    483
    Raymond Hettinger
    Jul 27, 2003
  2. shanx__=|;-

    very very very long integer

    shanx__=|;-, Oct 16, 2004, in forum: C Programming
    Replies:
    19
    Views:
    1,630
    Merrill & Michele
    Oct 19, 2004
  3. Abhishek Jha

    very very very long integer

    Abhishek Jha, Oct 16, 2004, in forum: C Programming
    Replies:
    4
    Views:
    427
    jacob navia
    Oct 17, 2004
  4. Jim

    Very new - Very confused

    Jim, Aug 4, 2003, in forum: ASP .Net Datagrid Control
    Replies:
    0
    Views:
    124
  5. rp
    Replies:
    1
    Views:
    539
    red floyd
    Nov 10, 2011
Loading...

Share This Page