dynamic variable names or using a variable as another's name

Discussion in 'Ruby' started by Peter Buckley, Feb 26, 2009.

  1. Hi-

    I've done some searching on this topic and it seems to be generally
    discouraged to use one variable's value as another variable's name (or
    part of it's name). People generally recommend a hash or array to answer
    this use case.

    I've seen these posted as "available but not recommended":

    eval("#{variable_name} = #[value}")

    or:

    self.instance_variable_set:)@var_name, value)

    or:

    x="myvar"
    myvar="hi"
    eval(x) -> "hi"

    I'm trying to write a short program and I'm thinking that I'm going in
    the wrong direction - can anyone give me some fresh ideas as an
    alternative to what I see as my "best solution?"

    I have string1, stringA (which won't be known till later) that is
    associated with string1, and then stringB and potentially stringC and
    stringD which are all associated with string1 and stringA.

    So I'm thinking that I want a hash, big_hash, with string1 as the key,
    and the value is another hash, string1_hash, with stringA as the key and
    the value is an array containing stringB,stringC,stringD.

    I realize I could name string1_hash anything, but I'm going to need
    multiple hashes as I iterate over a list of string1, string2, string3.
    I'd like big_hash to be somewhat permanent so I can re-use it elsewhere.

    I'm not looking for someone to solve the problem for me, but really just
    for other ideas beyond my clunky-semi-permanent data structure. Do I
    need to store these associated values in a database, rather than trying
    to build one out of these hashes? Is my direction of making big_hash
    semi-permanent a bad idea, and I should just keep re-using big_hash over
    and over as I iterate through my list of string1, string2, string3? As
    I'm asking the question I think that is the direction I'm going to try
    next, but I would still appreciate advice on this topic.

    TIA,
    Peter
    --
    Posted via http://www.ruby-forum.com/.
     
    Peter Buckley, Feb 26, 2009
    #1
    1. Advertising

  2. Peter Buckley

    matt neuburg Guest

    Peter Buckley <> wrote:

    > I have string1, stringA (which won't be known till later) that is
    > associated with string1, and then stringB and potentially stringC and
    > stringD which are all associated with string1 and stringA.


    That sounds like a hash where each value is a hash where each value is
    an array.

    > So I'm thinking that I want a hash, big_hash, with string1 as the key,
    > and the value is another hash, string1_hash, with stringA as the key and
    > the value is an array containing stringB,stringC,stringD.


    Great idea!

    > I realize I could name string1_hash anything, but I'm going to need
    > multiple hashes as I iterate over a list of string1, string2, string3.
    > I'd like big_hash to be somewhat permanent so I can re-use it elsewhere.


    There seems to be some confusion about the notion of "name" underlying
    all of this. There are not really any "names" in this story. Ruby isn't
    about "names". It's about pointers. string1_hash doesn't *have* a
    "name". It doesn't *need* a name. It is the value of some entry in
    big_hash. As long as you have a pointer to big_hash, you will always
    have access to its keys and values, and every one of those values is a
    hash of arrays, where the key is string1, string2, string3, whatever.
    You are there.

    So now the only question seems to be what you mean about the permanence
    of big_hash. Do you mean you'd like to store it between runs of your
    script? I'd use yaml for that. If you only mean that you need to be able
    to access it in various places during a single run of the script, then
    either make your pointer to it global or pass it around as a parameter.

    By the way, you *could* make all this a bit more rigorous by expressing
    it all as a class. I mention this only because a class might help you
    formalize the rules for the structure here. You don't *need* to do that,
    but it might help you catch errors down the road. m.

    --
    matt neuburg, phd = , http://www.tidbits.com/matt/
    Leopard - http://www.takecontrolbooks.com/leopard-customizing.html
    AppleScript - http://www.amazon.com/gp/product/0596102119
    Read TidBITS! It's free and smart. http://www.tidbits.com
     
    matt neuburg, Feb 26, 2009
    #2
    1. Advertising

  3. matt neuburg wrote:

    > There seems to be some confusion about the notion of "name" underlying
    > all of this. There are not really any "names" in this story. Ruby isn't
    > about "names". It's about pointers. string1_hash doesn't *have* a
    > "name". It doesn't *need* a name. It is the value of some entry in
    > big_hash. As long as you have a pointer to big_hash, you will always
    > have access to its keys and values, and every one of those values is a
    > hash of arrays, where the key is string1, string2, string3, whatever.
    > You are there.


    Ok, I'm learning that everything is an object, everything is a pointer
    in Ruby. But pointers though not required to have names, have names. It
    seems to make for more readable code in some circumstances.

    So here's my snippet: (forgive me, this is the first ruby I've tried so
    it is probably weak)

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

    p4.run_changes("-m5","//depot/path/...").each {
    |ch|
    string1 = ch["change"]
    bigHash[string1] = string1_hash
    }
    puts(bigHash.inspect)

    This iterates 5 times, each time with string1 being equal to a different
    string, so bigHash has 5 keys. The problem I'm having is that the value
    of each of the 5 keys is the same - string1_hash.

    To take an analogy from perl, I would have set $i to 0 and incremented
    such that when I did:

    bigHash[string1] = string${i}_hash

    That would set the value for each unique string1 key to a unique hash,
    each with unique a name that is meaningful to me and can be easily
    referenced later.

    So I guess I just don't know how to assign unique anonymous hashes as
    the value for each key in bigHash? So I don't care that string1_hash
    isn't named "string1_hash" - ok, makes sense - but then I guess I'm
    still asking this question about using one variable's value as another's
    name.

    If "no name" hash is the value of bigHash[string1], I guess coming from
    perl I'm not sure how to de-reference this appropriately, when I have
    the feeling that I don't need to de-reference anything. I just don't
    know how to correctly use the syntax to use the hash values of one hash
    as the thing that they are, a pointer to another hash that I want to
    populate with keys and values.

    Maybe I want to do somthing like this?

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

    p4.run_changes("-m5","//depot/path/...").each {
    |ch|
    string1 = ch["change"]
    bigHash[string1] = Hash.new { |h,k| h[k] = [] }
    }
    puts(bigHash.inspect)





    --
    Posted via http://www.ruby-forum.com/.
     
    Peter Buckley, Feb 26, 2009
    #3
  4. Peter Buckley

    matt neuburg Guest

    Peter Buckley <> wrote:

    > bigHash = Hash.new { |h,k| h[k] = [] }
    >
    > p4.run_changes("-m5","//depot/path/...").each {
    > |ch|
    > string1 = ch["change"]
    > bigHash[string1] = string1_hash
    > }
    > puts(bigHash.inspect)
    >
    > This iterates 5 times, each time with string1 being equal to a different
    > string, so bigHash has 5 keys. The problem I'm having is that the value
    > of each of the 5 keys is the same - string1_hash.


    Because you *set* them all to string_hash, in this line:

    > > bigHash[string1] = string1_hash


    What were you *trying* to do?

    Also, don't you have this upside down? I thought we agreed you were
    going to have *one* key called string1, whose value was an array, and
    you were going to put 5 different things into that array. I don't see
    you doing any of that.

    m.
    --
    matt neuburg, phd = , http://www.tidbits.com/matt/
    Leopard - http://www.takecontrolbooks.com/leopard-customizing.html
    AppleScript - http://www.amazon.com/gp/product/0596102119
    Read TidBITS! It's free and smart. http://www.tidbits.com
     
    matt neuburg, Feb 26, 2009
    #4
  5. matt neuburg wrote:
    > Peter Buckley <> wrote:
    >
    >> string, so bigHash has 5 keys. The problem I'm having is that the value
    >> of each of the 5 keys is the same - string1_hash.

    >
    > Because you *set* them all to string_hash, in this line:
    >
    >> > bigHash[string1] = string1_hash

    >
    > What were you *trying* to do?


    Right, that example I'm giving is incorrect - I want to set them like
    this (sorry, more perl-ish-ness):

    bigHash[string1] = ${string1}_hash
    bigHash[string2] = ${string2}_hash
    ...

    In my example, the local variable named string1 is changing each time we
    go through the loop, so what is actually happening is like this (still
    not doing what I want, assigning the same hash to each unique key):

    bigHash["12345"] = string1_hash
    bigHash["54241"] = string1_hash
    bigHash["86744"] = string1_hash
    ...

    > Also, don't you have this upside down? I thought we agreed you were
    > going to have *one* key called string1, whose value was an array, and
    > you were going to put 5 different things into that array. I don't see
    > you doing any of that.
    >
    > m.


    In bigHash I'm going to have one key for string1 (actually equal to
    string1, "12345") but an arbitrary number of keys like that - in my
    example (and hopefully clearer above) I have 3 keys each consisting of a
    unique string. I want each of their values to be a hash that contains a
    single key that evaluates to a different string, and the value of that
    key is the array containing one or more yet different strings.

    But I can't even get to the point where I have a unique hash as the
    value for each of my keys - after doing more reading I think I should be
    using the #{string1}_hash syntax to conveniently name my pointers to the
    unique hashes I'm creating each time through my iteration. Does that
    make more sense? Sorry my attempts to simplify my example have been
    confusing.

    Thanks for your help so far Matt, it is really helping me to "discuss"
    it with another person who knows more about Ruby than I do.
    --
    Posted via http://www.ruby-forum.com/.
     
    Peter Buckley, Feb 26, 2009
    #5
  6. Peter Buckley

    matt neuburg Guest

    matt neuburg, Feb 27, 2009
    #6
    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. Brian
    Replies:
    3
    Views:
    428
    Siemel Naran
    Apr 19, 2004
  2. Nmishra
    Replies:
    3
    Views:
    372
    Default User
    May 24, 2004
  3. wanwan
    Replies:
    3
    Views:
    434
    Alex Martelli
    Oct 14, 2005
  4. Bobby Chamness
    Replies:
    2
    Views:
    2,412
    Joe Smith
    Apr 22, 2007
  5. News123
    Replies:
    2
    Views:
    466
    John Machin
    Nov 26, 2008
Loading...

Share This Page