Patching strings together to make a variable

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.

Hi –

On Sun, 10 Sep 2006, Sy Ali wrote:

puts “#{$var(if $a == true then “iable” end)}”
What I’d really like to learn is how I can patch multiple strings
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 :slight_smile: Perl has these “soft” or “symbolic”
references, plus a whole chorus of people to tell you that you should
use hashes instead :slight_smile:

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

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 V.

On 9/10/06, David V. [email protected] 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… =)

How about:

puts “#{eval(‘$’ + ‘var’ + (if $a == true then “iable” end))}”

=> pass

Mike D.
http://www.rubywizards.com

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

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 S. [email protected]
http://www.stok.ca/~mike/

The “`Stok’ disclaimers” apply.

On 9/10/06, Mike S. [email protected] wrote:

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.

Hi –

On Mon, 11 Sep 2006, Mike D. 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

Hi –

On Mon, 11 Sep 2006, Axis S. wrote:

end

test(‘var’) #=> “pass”

Which brings us back to:

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

:slight_smile:

David

Sy Ali wrote:

particular obstacle can give a fresh point of view which sometimes
puts “#{@something_something}”
puts “#{@something_something}”
when “something_else” : puts “#{@something_something_else}”

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”

On 10-Sep-06, at 2:31 PM, [email protected] wrote:

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

:slight_smile:

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 S. [email protected]
http://www.stok.ca/~mike/

The “`Stok’ disclaimers” apply.

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

code, perhaps dropping this trick.
My original method would do this:

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 S. [email protected]
http://www.stok.ca/~mike/

The “`Stok’ disclaimers” apply.

On 9/10/06, Mike D. [email protected] 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

On 9/10/06, Axis S. [email protected] 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. =)

Hi –

On Mon, 11 Sep 2006, Mike S. wrote:

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

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.

On 9/10/06, Mike D. [email protected] 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. =)

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 :slight_smile:

Mike D.
http://www.rubywizards.com

On 9/10/06, John W. Long [email protected] wrote:

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

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.