Using hash keys as object name

How do I assign hash’s key as an object name? For example I have a hash
as:

fruits = {“apple” => [“green”, “red”], “melons” => [“water”, “musk”] }

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.

thanks,
neuby.

On Wed, Apr 20, 2011 at 8:07 AM, neubyr [email protected] wrote:

How do I assign hash’s key as an object name? For example I have a hash as:

fruits = {“apple” => [“green”, “red”], “melons” => [“water”, “musk”] }

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

What are you trying to accomplish?

Kind regards

robert

Neubyr N. wrote in post #993923:

How do I assign hash’s key as an object name? For example I have a hash
as:

fruits = {“apple” => [“green”, “red”], “melons” => [“water”, “musk”] }

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.

thanks,
neuby.

fruits = {“apple” => [“green”, “red”], “melons” => [“water”, “musk”] }

h = {}

fruits.keys.each do |key|
h[key] = “”
end

p h

–output:–
{“apple”=>"", “melons”=>""}

h[‘apple’] = 10
p h

–output:–
{“apple”=>10, “melons”=>""}

In short, there is no need to create variables with those names. Hashes
associate names(keys) with values, so use a hash. Your
question usually comes up in the form: “Hi, I want to create variables
with the names a1, a2, a3, a4, a5 … a100. How can I do that?” The
answer is: that’s what arrays are for. You just have to settle for the
names being a[0], a[1], a[2] … a[99] instead.

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

On Wed, Apr 20, 2011 at 11:19 PM, neubyr [email protected] 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.

Kind regards

robert

Thanks a lot for explaining the basics… Changed the implementation.


neuby