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.

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:

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.

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

Neubyr Neubyr 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"=>""}

--output:--

···

--
Posted via http://www.ruby-forum.com/\.

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:

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

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

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.

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

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.

Kind regards

robert

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/