There is usually no point in dynamically generating local variable
names - which is what you are trying to attempt. The reason is that
your code needs to use them before they are known - otherwise it
cannot see them. Example:
09:35:55 ~$ ruby19 b.rb
name is foo
attempt 1
[:name, :e, :b, :foo]
123
attempt 2
[:name, :e, :b, :foo]
123
attempt 3
[:name, :e, :b, :foo]
123
09:35:57 ~$ cat -n b.rb
1
2 name='foo'
3 puts "name is #{name}"
4
5 puts "attempt 1"
6
7
8 begin
9 eval "#{name}=123"
10 p local_variables
11 eval "puts #{name}"
12 rescue Exception => e
13 puts e
14 end
15
16 puts "attempt 2"
17
18 b = binding
19 eval "#{name}=123", b
20 p local_variables
21 eval "puts #{name}", b
22
23 puts "attempt 3"
24
25 foo=nil
26 eval "#{name}=123"
27 p local_variables
28 eval "puts #{name}"
09:36:05 ~$
Note there are some special cases where it can make sense. These
typically involve meta programming (e.g. ERB does it).
What are you trying to accomplish?
Kind regards
robert
···
On Wed, Apr 20, 2011 at 8:07 AM, neubyr <neubyr@gmail.com> wrote:
How do I assign hash's key as an object name? For example I have a hash as:
Thanks for the help Robert. Following is a scenario I am trying to implement:
I want to create File objects based on a hash. The 'fruits' hash will
be created based on user input (yaml file), so I don't know how long
the hash will be beforehand. For each key in this hash I would like to
instantiate a File object with object/var name same as hash key. In
future I may have a subclass of File class say UserFile class. The
UserFile objects will be instantiated in a similar manner as File
object, in addition they will get hash values passed on as variables.
···
--
neubyr.
On Wed, Apr 20, 2011 at 2:36 AM, Robert Klemme <shortcutter@googlemail.com> wrote:
On Wed, Apr 20, 2011 at 8:07 AM, neubyr <neubyr@gmail.com> wrote:
How do I assign hash's key as an object name? For example I have a hash as:
I would like to create a File or String objects by reading above hash,
something like
fruits.keys.each {|k| "#{k}" = String.new}
Any hints or suggestions on how to do this will be really helpful.
There is usually no point in dynamically generating local variable
names - which is what you are trying to attempt. The reason is that
your code needs to use them before they are known - otherwise it
cannot see them. Example:
09:35:55 ~$ ruby19 b.rb
name is foo
attempt 1
[:name, :e, :b, :foo]
123
attempt 2
[:name, :e, :b, :foo]
123
attempt 3
[:name, :e, :b, :foo]
123
09:35:57 ~$ cat -n b.rb
1
2 name='foo'
3 puts "name is #{name}"
4
5 puts "attempt 1"
6
7
8 begin
9 eval "#{name}=123"
10 p local_variables
11 eval "puts #{name}"
12 rescue Exception => e
13 puts e
14 end
15
16 puts "attempt 2"
17
18 b = binding
19 eval "#{name}=123", b
20 p local_variables
21 eval "puts #{name}", b
22
23 puts "attempt 3"
24
25 foo=nil
26 eval "#{name}=123"
27 p local_variables
28 eval "puts #{name}"
09:36:05 ~$
Note there are some special cases where it can make sense. These
typically involve meta programming (e.g. ERB does it).
There is no need to create local variables for these File objects - in
fact, it won't work. You rather want to create a second Hash.
FileData = Struct.new :io, :attributes
user_input = { ... } # from YAML
files = {}
user_input.each do |k,v|
files[k] = FileData.new File.open(k), v # whatever else
end
# use files
...
# close files
files.each do |k,v|
v.io.close
end
Note, I deliberately left out error handling in order to keep the code simple.
Kind regards
robert
···
On Wed, Apr 20, 2011 at 11:19 PM, neubyr <neubyr@gmail.com> wrote:
Thanks for the help Robert. Following is a scenario I am trying to implement:
I want to create File objects based on a hash. The 'fruits' hash will
be created based on user input (yaml file), so I don't know how long
the hash will be beforehand. For each key in this hash I would like to
instantiate a File object with object/var name same as hash key. In
future I may have a subclass of File class say UserFile class. The
UserFile objects will be instantiated in a similar manner as File
object, in addition they will get hash values passed on as variables.
Thanks a lot for explaining the basics.. Changed the implementation.
···
--
neuby
On 4/21/11, Robert Klemme <shortcutter@googlemail.com> wrote:
On Wed, Apr 20, 2011 at 11:19 PM, neubyr <neubyr@gmail.com> wrote:
Thanks for the help Robert. Following is a scenario I am trying to
implement:
I want to create File objects based on a hash. The 'fruits' hash will
be created based on user input (yaml file), so I don't know how long
the hash will be beforehand. For each key in this hash I would like to
instantiate a File object with object/var name same as hash key. In
future I may have a subclass of File class say UserFile class. The
UserFile objects will be instantiated in a similar manner as File
object, in addition they will get hash values passed on as variables.
There is no need to create local variables for these File objects - in
fact, it won't work. You rather want to create a second Hash.
FileData = Struct.new :io, :attributes
user_input = { ... } # from YAML
files = {}
user_input.each do |k,v|
files[k] = FileData.new File.open(k), v # whatever else
end
# use files
...
# close files
files.each do |k,v|
v.io.close
end
Note, I deliberately left out error handling in order to keep the code
simple.