patching strings together to make a variable

Discussion in 'Ruby' started by Sy Ali, Sep 10, 2006.

  1. Sy Ali

    Sy Ali Guest

    I'm curious to know if I can patch multiple things together to make a variable.

    I have some imaginary code snippets. The most direct way I can think
    of is something like this:

    $a = true
    $var = "fail"
    $variable = "pass"

    puts "#{$var(if $a == true then "iable" end)}"

    since $a == true, I would like this to become:
    puts "#{$variable}"

    But this doesn't work. I didn't expect it to, but is something like
    this possible? Am I stuck with this? :

    puts "#{if $a == true then $variable else $var end}"


    What I'd really like to learn is how I can patch multiple strings
    together and call it a variable. I think I'm just missing some simple
    piece of this puzzle..

    The imaginary code would be:

    ab = "pass"
    puts ("a" + "b").to_variable

    Or to a global, an instance variable, etc.. envisioned like this:

    puts $("a" + "b")
    puts @("a" + "b")


    If there's a simple way to do this, a code snippet or a pointer to a
    manual reference would be all I need.
     
    Sy Ali, Sep 10, 2006
    #1
    1. Advertising

  2. Sy Ali

    Guest

    Hi --

    On Sun, 10 Sep 2006, Sy Ali wrote:

    > I'm curious to know if I can patch multiple things together to make a
    > variable.
    >
    > I have some imaginary code snippets. The most direct way I can think
    > of is something like this:
    >
    > $a = true
    > $var = "fail"
    > $variable = "pass"
    >
    > puts "#{$var(if $a == true then "iable" end)}"
    >
    > since $a == true, I would like this to become:
    > puts "#{$variable}"
    >
    > But this doesn't work. I didn't expect it to, but is something like
    > this possible? Am I stuck with this? :
    >
    > puts "#{if $a == true then $variable else $var end}"
    >
    >
    > What I'd really like to learn is how I can patch multiple strings
    > together and call it a variable. I think I'm just missing some simple
    > piece of this puzzle..
    >
    > The imaginary code would be:
    >
    > ab = "pass"
    > puts ("a" + "b").to_variable
    >
    > Or to a global, an instance variable, etc.. envisioned like this:
    >
    > puts $("a" + "b")
    > puts @("a" + "b")
    >
    >
    > If there's a simple way to do this, a code snippet or a pointer to a
    > manual reference would be all I need.


    http://www.perl.org :) Perl has these "soft" or "symbolic"
    references, plus a whole chorus of people to tell you that you should
    use hashes instead :)

    Ruby gives you ways to examine available existing variables, and you
    can pry into them:

    @ab = "pass"
    puts instance_variable_get("@#{"a" + "b"}")

    and so on.


    David

    --
    David A. Black |
    Author of "Ruby for Rails" [1] | Ruby/Rails training & consultancy [3]
    DABlog (DAB's Weblog) [2] | Co-director, Ruby Central, Inc. [4]
    [1] http://www.manning.com/black | [3] http://www.rubypowerandlight.com
    [2] http://dablog.rubypal.com | [4] http://www.rubycentral.org
     
    , Sep 10, 2006
    #2
    1. Advertising

  3. Sy Ali wrote:
    > What I'd really like to learn is how I can patch multiple strings
    > together and call it a variable. I think I'm just missing some simple
    > piece of this puzzle..
    >
    > The imaginary code would be:
    >
    > ab = "pass"
    > puts ("a" + "b").to_variable
    >
    >


    This sounds very, very PHP to me. And subjectively speaking, I think
    variable variables from that language are the worst abomination in a
    structured programming language since VB goto.

    Does that really make code clearer instead of just "clever"?

    David Vallner
     
    David Vallner, Sep 10, 2006
    #3
  4. Sy Ali

    Sy Ali Guest

    On 9/10/06, David Vallner <> wrote:
    > > ab = "pass"
    > > puts ("a" + "b").to_variable

    >
    > This sounds very, very PHP to me. And subjectively speaking, I think
    > variable variables from that language are the worst abomination in a
    > structured programming language since VB goto.
    >
    > Does that really make code clearer instead of just "clever"?


    I know nothing of PHP, but this trick would make my code much clearer.
    With David.first's recommendation of instance_variable_get I can
    re-use blocks of code much more intelligently.

    Previously, I've been duplicating methods and just renaming a single
    variable.. (just to ensure that method1 works the same as method2) a
    variation of this would be cleaner I think.

    My code is still quite hackish, so it's likely that I'll figure things
    out in some time, and will be able to evolve towards even cleaner
    code, perhaps dropping this trick.


    Thanks for the help Davids.. =)
     
    Sy Ali, Sep 10, 2006
    #4
  5. Sy Ali

    Mike Stok Guest

    On 10-Sep-06, at 11:52 AM, Sy Ali wrote:

    > On 9/10/06, David Vallner <> wrote:
    >> > ab = "pass"
    >> > puts ("a" + "b").to_variable

    >>
    >> This sounds very, very PHP to me. And subjectively speaking, I think
    >> variable variables from that language are the worst abomination in a
    >> structured programming language since VB goto.
    >>
    >> Does that really make code clearer instead of just "clever"?

    >
    > I know nothing of PHP, but this trick would make my code much clearer.
    > With David.first's recommendation of instance_variable_get I can
    > re-use blocks of code much more intelligently.
    >
    > Previously, I've been duplicating methods and just renaming a single
    > variable.. (just to ensure that method1 works the same as method2) a
    > variation of this would be cleaner I think.
    >
    > My code is still quite hackish, so it's likely that I'll figure things
    > out in some time, and will be able to evolve towards even cleaner
    > code, perhaps dropping this trick.


    What are you actually trying to do? Sometimes stepping back from a
    particular obstacle can give a fresh point of view which sometimes
    leads to "nicer" code.

    Mention of duplicating methods and renaming a single variable hints
    strongly there may be more ways to skin this cat.

    Mike

    --

    Mike Stok <>
    http://www.stok.ca/~mike/

    The "`Stok' disclaimers" apply.
     
    Mike Stok, Sep 10, 2006
    #5
  6. Sy Ali

    Mike Dvorkin Guest

    How about:

    puts "#{eval('$' + 'var' + (if $a == true then "iable" end))}"
    # => pass

    Mike Dvorkin
    http://www.rubywizards.com



    On Sep 10, 2006, at 6:50 AM, Sy Ali wrote:

    > $a = true
    > $var = "fail"
    > $variable = "pass"
    >
    > puts "#{$var(if $a == true then "iable" end)}"
    >
    > since $a == true, I would like this to become:
    > puts "#{$variable}"
     
    Mike Dvorkin, Sep 10, 2006
    #6
  7. Sy Ali

    Guest

    Hi --

    On Mon, 11 Sep 2006, Mike Dvorkin wrote:

    > How about:
    >
    > puts "#{eval('$' + 'var' + (if $a == true then "iable" end))}"
    > # => pass


    If your if fails you end up adding nil to a string, which will give
    you an error.

    So.....

    puts eval('$' + 'var' + ($a ? "iable" : ""))

    or something.


    David

    > Mike Dvorkin
    > http://www.rubywizards.com
    >
    >
    >
    > On Sep 10, 2006, at 6:50 AM, Sy Ali wrote:
    >
    >> $a = true
    >> $var = "fail"
    >> $variable = "pass"
    >>
    >> puts "#{$var(if $a == true then "iable" end)}"
    >>
    >> since $a == true, I would like this to become:
    >> puts "#{$variable}"

    >
    >


    --
    David A. Black |
    Author of "Ruby for Rails" [1] | Ruby/Rails training & consultancy [3]
    DABlog (DAB's Weblog) [2] | Co-director, Ruby Central, Inc. [4]
    [1] http://www.manning.com/black | [3] http://www.rubypowerandlight.com
    [2] http://dablog.rubypal.com | [4] http://www.rubycentral.org
     
    , Sep 10, 2006
    #7
  8. Sy Ali

    Sy Ali Guest

    On 9/10/06, Mike Stok <> wrote:
    > > Previously, I've been duplicating methods and just renaming a single
    > > variable.. (just to ensure that method1 works the same as method2) a
    > > variation of this would be cleaner I think.
    > >
    > > My code is still quite hackish, so it's likely that I'll figure things
    > > out in some time, and will be able to evolve towards even cleaner
    > > code, perhaps dropping this trick.

    >
    > What are you actually trying to do? Sometimes stepping back from a
    > particular obstacle can give a fresh point of view which sometimes
    > leads to "nicer" code.
    >
    > Mention of duplicating methods and renaming a single variable hints
    > strongly there may be more ways to skin this cat.


    I was just looking for an alternative to the classic if/then/else.

    My original method would do this:

    def test1
    puts "#{@something_something}"
    end

    def test2
    puts "#{@something_something_else}"
    end

    or maybe I could have done this:

    def test(string)
    if string == "something" then
    puts "#{@something_something}"
    elsif string == "something_else" then
    puts "#{@something_something_else}"
    end
    end

    What if I wanted to expand this a thousand-fold? I'd have to do this:

    def test(string)
    case string
    when "something" : puts "#{@something_something}"
    when "something_else" : puts "#{@something_something_else}"
    # ... repeated many more times
    end
    end

    But that thousand-line case could be replaced with a one-liner:

    def test(string)
    puts "#{instance_variable_get("@#{string + "_something"}")}"
    end


    I got here because I was looking at my inelegant code and wanted to
    know how it could be simplified when faced with greater use.

    Thinking in infinites.. yes, it's optimising early, but I wanted to
    learn something new.
     
    Sy Ali, Sep 10, 2006
    #8
  9. Sy Ali

    Axis Sivitz Guest

    Sy Ali wrote:
    > On 9/10/06, Mike Stok <> wrote:
    > > > Previously, I've been duplicating methods and just renaming a single
    > > > variable.. (just to ensure that method1 works the same as method2) a
    > > > variation of this would be cleaner I think.
    > > >
    > > > My code is still quite hackish, so it's likely that I'll figure things
    > > > out in some time, and will be able to evolve towards even cleaner
    > > > code, perhaps dropping this trick.

    > >
    > > What are you actually trying to do? Sometimes stepping back from a
    > > particular obstacle can give a fresh point of view which sometimes
    > > leads to "nicer" code.
    > >
    > > Mention of duplicating methods and renaming a single variable hints
    > > strongly there may be more ways to skin this cat.

    >
    > I was just looking for an alternative to the classic if/then/else.
    >
    > My original method would do this:
    >
    > def test1
    > puts "#{@something_something}"
    > end
    >
    > def test2
    > puts "#{@something_something_else}"
    > end
    >
    > or maybe I could have done this:
    >
    > def test(string)
    > if string == "something" then
    > puts "#{@something_something}"
    > elsif string == "something_else" then
    > puts "#{@something_something_else}"
    > end
    > end
    >
    > What if I wanted to expand this a thousand-fold? I'd have to do this:
    >
    > def test(string)
    > case string
    > when "something" : puts "#{@something_something}"
    > when "something_else" : puts "#{@something_something_else}"
    > # ... repeated many more times
    > end
    > end
    >
    > But that thousand-line case could be replaced with a one-liner:
    >
    > def test(string)
    > puts "#{instance_variable_get("@#{string + "_something"}")}"
    > end
    >
    >
    > I got here because I was looking at my inelegant code and wanted to
    > know how it could be simplified when faced with greater use.
    >
    > Thinking in infinites.. yes, it's optimising early, but I wanted to
    > learn something new.


    Uh...if you have so many similarly named variables, it sounds like you
    should be using an array or a map.

    The map could be set up with the keys (a certain string) indexing to
    the values of your old variables.

    @some_map['var'] = "pass"

    def test(string)
    puts @some_map[string]
    end

    test('var') #=> "pass"
     
    Axis Sivitz, Sep 10, 2006
    #9
  10. Sy Ali

    Guest

    Hi --

    On Mon, 11 Sep 2006, Axis Sivitz wrote:

    > Uh...if you have so many similarly named variables, it sounds like you
    > should be using an array or a map.
    >
    > The map could be set up with the keys (a certain string) indexing to
    > the values of your old variables.
    >
    > @some_map['var'] = "pass"
    >
    > def test(string)
    > puts @some_map[string]
    > end
    >
    > test('var') #=> "pass"


    Which brings us back to:

    > http://www.perl.org :) Perl has these "soft" or "symbolic"
    > references, plus a whole chorus of people to tell you that you
    > should use hashes instead :)


    :)


    David

    --
    David A. Black |
    Author of "Ruby for Rails" [1] | Ruby/Rails training & consultancy [3]
    DABlog (DAB's Weblog) [2] | Co-director, Ruby Central, Inc. [4]
    [1] http://www.manning.com/black | [3] http://www.rubypowerandlight.com
    [2] http://dablog.rubypal.com | [4] http://www.rubycentral.org
     
    , Sep 10, 2006
    #10
  11. Sy Ali

    Mike Stok Guest

    On 10-Sep-06, at 2:31 PM, wrote:

    > Hi --
    >
    > On Mon, 11 Sep 2006, Axis Sivitz wrote:
    >
    >> Uh...if you have so many similarly named variables, it sounds like
    >> you
    >> should be using an array or a map.
    >>
    >> The map could be set up with the keys (a certain string) indexing to
    >> the values of your old variables.
    >>
    >> @some_map['var'] = "pass"
    >>
    >> def test(string)
    >> puts @some_map[string]
    >> end
    >>
    >> test('var') #=> "pass"

    >
    > Which brings us back to:
    >
    >> http://www.perl.org :) Perl has these "soft" or "symbolic"
    >> references, plus a whole chorus of people to tell you that you
    >> should use hashes instead :)

    >
    > :)


    One of the reasons for the Perl chorus is that in Perl the "soft
    references" can only point to non-lexical variables, and this can
    cause much opportunity for enlightenment later!

    #!/usr/bin/env perl

    # use strict;
    # use warnings;

    $foo = 'foo1';
    my $foo = 'foo2';

    $soft_ref = 'foo';
    $real_ref = \$foo;

    print "soft says $$soft_ref\n";
    print "real says $$real_ref\n";

    __END__

    produces:

    soft says foo1
    real says foo2

    ... which is one of the reasons the strict and warnings pragmata are
    considered useful.

    Mike

    --

    Mike Stok <>
    http://www.stok.ca/~mike/

    The "`Stok' disclaimers" apply.
     
    Mike Stok, Sep 10, 2006
    #11
  12. Sy Ali

    Mike Stok Guest

    On 10-Sep-06, at 1:57 PM, Sy Ali wrote:

    > On 9/10/06, Mike Stok <> wrote:
    >> > Previously, I've been duplicating methods and just renaming a

    >> single
    >> > variable.. (just to ensure that method1 works the same as

    >> method2) a
    >> > variation of this would be cleaner I think.
    >> >
    >> > My code is still quite hackish, so it's likely that I'll figure

    >> things
    >> > out in some time, and will be able to evolve towards even cleaner
    >> > code, perhaps dropping this trick.

    >>
    >> What are you actually trying to do? Sometimes stepping back from a
    >> particular obstacle can give a fresh point of view which sometimes
    >> leads to "nicer" code.
    >>
    >> Mention of duplicating methods and renaming a single variable hints
    >> strongly there may be more ways to skin this cat.

    >
    > I was just looking for an alternative to the classic if/then/else.
    >
    > My original method would do this:
    >
    > def test1
    > puts "#{@something_something}"
    > end
    >
    > def test2
    > puts "#{@something_something_else}"
    > end
    >
    > or maybe I could have done this:
    >
    > def test(string)
    > if string == "something" then
    > puts "#{@something_something}"
    > elsif string == "something_else" then
    > puts "#{@something_something_else}"
    > end
    > end
    >
    > What if I wanted to expand this a thousand-fold? I'd have to do this:
    >
    > def test(string)
    > case string
    > when "something" : puts "#{@something_something}"
    > when "something_else" : puts "#{@something_something_else}"
    > # ... repeated many more times
    > end
    > end
    >
    > But that thousand-line case could be replaced with a one-liner:
    >
    > def test(string)
    > puts "#{instance_variable_get("@#{string + "_something"}")}"
    > end
    >
    >
    > I got here because I was looking at my inelegant code and wanted to
    > know how it could be simplified when faced with greater use.
    >
    > Thinking in infinites.. yes, it's optimising early, but I wanted to
    > learn something new.


    Depending on what's in your instance variables and how you call test
    you might be able to throw away some punctuation e.g.

    def test(string)
    puts instance_variable_get('@something_' + string)
    end

    Mike

    --

    Mike Stok <>
    http://www.stok.ca/~mike/

    The "`Stok' disclaimers" apply.
     
    Mike Stok, Sep 10, 2006
    #12
  13. Sy Ali

    Sy Ali Guest

    On 9/10/06, Axis Sivitz <> wrote:
    > Uh...if you have so many similarly named variables, it sounds like you
    > should be using an array or a map.
    >
    > The map could be set up with the keys (a certain string) indexing to
    > the values of your old variables.


    Oh, good point. =)
     
    Sy Ali, Sep 10, 2006
    #13
  14. Sy Ali

    Sy Ali Guest

    On 9/10/06, Mike Dvorkin <> wrote:
    > How about:
    >
    > puts "#{eval('$' + 'var' + (if $a == true then "iable" end))}"
    > # => pass



    I can see the value with this, but what if I wanted to add a number to
    the resulting variable?

    Something like this:

    a = "var"
    b = "iable"
    $variable = 1
    eval('$' + 'var' + 'iable') += 1
     
    Sy Ali, Sep 10, 2006
    #14
  15. Sy Ali

    Guest

    Hi --

    On Mon, 11 Sep 2006, Mike Stok wrote:

    >
    > On 10-Sep-06, at 2:31 PM, wrote:
    >
    >> Which brings us back to:
    >>
    >>> http://www.perl.org :) Perl has these "soft" or "symbolic"
    >>> references, plus a whole chorus of people to tell you that you
    >>> should use hashes instead :)

    >>
    >> :)

    >
    > One of the reasons for the Perl chorus is that in Perl the "soft references"
    > can only point to non-lexical variables, and this can cause much opportunity
    > for enlightenment later!


    Interesting. I've always been part of the "use hashes" chorus (long
    ago in Perl and now in Ruby), though I can't remember whether I ever
    knew this or just vaguely perceived symbolic references as (usually)
    involving very brittle and tightly coupled code.


    David

    --
    David A. Black |
    Author of "Ruby for Rails" [1] | Ruby/Rails training & consultancy [3]
    DABlog (DAB's Weblog) [2] | Co-director, Ruby Central, Inc. [4]
    [1] http://www.manning.com/black | [3] http://www.rubypowerandlight.com
    [2] http://dablog.rubypal.com | [4] http://www.rubycentral.org
     
    , Sep 10, 2006
    #15
  16. Sy Ali

    John W. Long Guest

    Sy Ali wrote:
    > The imaginary code would be:
    >
    > ab = "pass"
    > puts ("a" + "b").to_variable


    I've occasionally used something like this with methods. For instance, I
    recently wrote an Exporter that worked something like this:

    class Exporter
    def export(format=:yaml)
    method = "export_#{format}"
    if respond_to?(method)
    send(method)
    else
    raise "invalid format"
    end
    end

    private

    def export_yaml
    ...
    end

    def export_xml
    ...
    end
    end

    Not sure what you are doing, but perhaps a method oriented solution
    would work better.

    --
    John Long
    http://wiseheartdesign.com
    http://radiantcms.org
     
    John W. Long, Sep 10, 2006
    #16
  17. Sy Ali

    Mike Dvorkin Guest

    I'm not quite clear what exactly you're trying to achieve, but you
    can perform any operation on $variable by making it part of eval()
    string:

    puts eval('$' + 'var' + 'iable += 1')
    #=> 2
    puts eval('$' + 'var' + 'iable *=' + 10.to_s)
    #=> 20

    HTH :)

    Mike Dvorkin
    http://www.rubywizards.com



    On Sep 10, 2006, at 1:22 PM, Sy Ali wrote:

    > On 9/10/06, Mike Dvorkin <> wrote:
    >> How about:
    >>
    >> puts "#{eval('$' + 'var' + (if $a == true then "iable" end))}"
    >> # => pass

    >
    >
    > I can see the value with this, but what if I wanted to add a number to
    > the resulting variable?
    >
    > Something like this:
    >
    > a = "var"
    > b = "iable"
    > $variable = 1
    > eval('$' + 'var' + 'iable') += 1
    >
     
    Mike Dvorkin, Sep 10, 2006
    #17
  18. Sy Ali

    Sy Ali Guest

    On 9/10/06, Mike Dvorkin <> wrote:
    > I'm not quite clear what exactly you're trying to achieve, but you
    > can perform any operation on $variable by making it part of eval()
    > string:
    >
    > puts eval('$' + 'var' + 'iable += 1')
    > #=> 2
    > puts eval('$' + 'var' + 'iable *=' + 10.to_s)
    > #=> 20


    That's definitely what I wanted for one little snippet I was working
    on. Thanks. =)
     
    Sy Ali, Sep 10, 2006
    #18
  19. Sy Ali

    Sy Ali Guest

    On 9/10/06, John W. Long <> wrote:
    > I've occasionally used something like this with methods. For instance, I
    > recently wrote an Exporter that worked something like this:


    <snip>

    > Not sure what you are doing, but perhaps a method oriented solution
    > would work better.


    That's pretty interesting.. I think I could adapt that for some other
    stuff I've been thinking about.
     
    Sy Ali, Sep 10, 2006
    #19
    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. Edward Yang
    Replies:
    6
    Views:
    1,553
    Scott Allen
    Feb 18, 2005
  2. DaveB
    Replies:
    0
    Views:
    374
    DaveB
    Oct 26, 2004
  3. Tomek Grzywalski
    Replies:
    1
    Views:
    338
    brucie
    Apr 3, 2004
  4. Thomas G. Apostolou

    Problem patching SimpleXMLRPCServer.py

    Thomas G. Apostolou, Dec 6, 2005, in forum: Python
    Replies:
    0
    Views:
    293
    Thomas G. Apostolou
    Dec 6, 2005
  5. Ben

    Strings, Strings and Damned Strings

    Ben, Jun 22, 2006, in forum: C Programming
    Replies:
    14
    Views:
    767
    Malcolm
    Jun 24, 2006
Loading...

Share This Page