eval question

P

Peter Szinek

Hi,

I am setting up a few variables based on user input with the following
code snippet:

==================================
vars = %w{a b c}

vars.each do |var|
print "#{var} = "
val = gets
eval("$#{var}=#{val.chomp}")
end

#use a, b, c here for something
==================================

What I don't like about this code is the use of global variables.
However, I have to use them - or otherwise a,b,c will be already out of
scope at the place I need them.

Another possibility would be to use constants, i.e.

vars = %w{A B C}

which would work well - however, since I am repeating the process more
times, from the second iteration on I am getting warnings that A, B, C
etc were already initialized, which is not nice.

I guess yet another possibility would be to wrap a class around this
stuff and use instance_eval or something like that - but a class that
serves solely this purpose looks to heavy to me...

Any other ideas?

TIA,
Peter

__
http://www.rubyrailways.com
 
J

Joel VanderWerf

Peter said:
Hi,

I am setting up a few variables based on user input with the following
code snippet:

==================================
vars = %w{a b c}

vars.each do |var|
print "#{var} = "
val = gets
eval("$#{var}=#{val.chomp}")
end

#use a, b, c here for something
==================================

What I don't like about this code is the use of global variables.
However, I have to use them - or otherwise a,b,c will be already out of
scope at the place I need them.

Use a hash?

vars = {
"a" => nil,
"b" => nil,
"c" => nil,
}

def get_input vars
vars.keys.each do |var|
print "#{var} = "
val = gets
vars[var] = val.chomp
eval("$#{var}=#{val.chomp}")
end
end

get_input vars
p vars
__END__
a = 1
b = 2
c = 3
{"a"=>"1", "b"=>"2", "c"=>"3"}


You can use instance_eval with the hash, as you suggested:

module AcessibleKeys
def method_missing(m, *rest)
if rest.empty?
fetch(m.to_s)
else
super
end
end
end

vars.extend AcessibleKeys

get_input vars
p vars

vars.instance_eval do
puts "a+b+c = #{a+b+c}"
end
__END__
a = 1
b = 2
c = 3
{"a"=>"1", "b"=>"2", "c"=>"3"}
a+b+c = 123
 
P

Peter Szinek

Hey Joel, that looks great! Thanks a lot (for solving the mystery of the
sprintf problem, too :)
 
M

matt neuburg

Peter Szinek said:
Hi,

I am setting up a few variables based on user input with the following
code snippet:

==================================
vars = %w{a b c}

vars.each do |var|
print "#{var} = "
val = gets
eval("$#{var}=#{val.chomp}")
end

#use a, b, c here for something
==================================

What I don't like about this code is the use of global variables.
However, I have to use them - or otherwise a,b,c will be already out of
scope at the place I need them.

Another possibility would be to use constants, i.e.

vars = %w{A B C}

which would work well - however, since I am repeating the process more
times, from the second iteration on I am getting warnings that A, B, C
etc were already initialized, which is not nice.

I guess yet another possibility would be to wrap a class around this
stuff and use instance_eval or something like that - but a class that
serves solely this purpose looks to heavy to me...

Any other ideas?

Pass a binding?

a = 1
b = 2
c = 3

def goforit(w, bind)
w.each do |v|
eval("#{v} = 'heehee'", bind)
end
end

goforit %w{a b c}, binding
puts a, b, c

m.
 

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
474,129
Messages
2,570,770
Members
47,329
Latest member
FidelRauch

Latest Threads

Top