using hash keys as object name

N

neubyr

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

Robert Klemme

How do I assign hash's key as an object name? =A0For example I have a has= h as:

=A0fruits =3D {"apple" =3D> ["green", "red"], "melons" =3D> ["water", "mu= sk"] }

I would like to create a File or String objects by reading above hash,
something like

=A0fruits.keys.each {|k| "#{k}" =3D 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=3D'foo'
3 puts "name is #{name}"
4
5 puts "attempt 1"
6
7
8 begin
9 eval "#{name}=3D123"
10 p local_variables
11 eval "puts #{name}"
12 rescue Exception =3D> e
13 puts e
14 end
15
16 puts "attempt 2"
17
18 b =3D binding
19 eval "#{name}=3D123", b
20 p local_variables
21 eval "puts #{name}", b
22
23 puts "attempt 3"
24
25 foo=3Dnil
26 eval "#{name}=3D123"
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

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

7stud --

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

neubyr

Thanks for the help Robert. Following is a scenario I am trying to implemen=
t:
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.


How do I assign hash's key as an object name? =A0For example I have a ha= sh as:

=A0fruits =3D {"apple" =3D> ["green", "red"], "melons" =3D> ["water", "m= usk"] }

I would like to create a File or String objects by reading above hash,
something like

=A0fruits.keys.each {|k| "#{k}" =3D 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. =A0The reason is that
your code needs to use them before they are known - otherwise it
cannot see them. =A0Example:

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
=A0 =A0 1
=A0 =A0 2 =A0name=3D'foo'
=A0 =A0 3 =A0puts "name is #{name}"
=A0 =A0 4
=A0 =A0 5 =A0puts "attempt 1"
=A0 =A0 6
=A0 =A0 7
=A0 =A0 8 =A0begin
=A0 =A0 9 =A0 =A0eval "#{name}=3D123"
=A0 =A010 =A0 =A0p local_variables
=A0 =A011 =A0 =A0eval "puts #{name}"
=A0 =A012 =A0rescue Exception =3D> e
=A0 =A013 =A0 =A0puts e
=A0 =A014 =A0end
=A0 =A015
=A0 =A016 =A0puts "attempt 2"
=A0 =A017
=A0 =A018 =A0b =3D binding
=A0 =A019 =A0eval "#{name}=3D123", b
=A0 =A020 =A0p local_variables
=A0 =A021 =A0eval "puts #{name}", b
=A0 =A022
=A0 =A023 =A0puts "attempt 3"
=A0 =A024
=A0 =A025 =A0foo=3Dnil
=A0 =A026 =A0eval "#{name}=3D123"
=A0 =A027 =A0p local_variables
=A0 =A028 =A0eval "puts #{name}"
09:36:05 ~$

Note there are some special cases where it can make sense. =A0These
typically involve meta programming (e.g. ERB does it).

What are you trying to accomplish?

Kind regards

robert
 
R

Robert Klemme

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
 
N

neubyr

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

--
neuby

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
 

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
473,770
Messages
2,569,583
Members
45,074
Latest member
StanleyFra

Latest Threads

Top