@my_hsh is nil because it is being called before the initialize
method is run.
@my_hsh = my_hsh
is run when the object is initialised
the @my_hash.each
loop is being called when the class is being initialialised, which is before Foo.new
is called.
To make this work you would need to create a method on the Foo class itself then call that method against the food class.
e.g.
# frozen_string_literal: true
class Foo
def self.define_methods(hash)
hash.each do |k, v|
define_method k do
v
end
end
end
end
hsh = {
first: 1,
second: 2,
}
Foo.define_methods(hsh)
my_foo = Foo.new
puts my_foo.first
puts my_foo.second
If you really want to define the methods on instantiation you could do it 2 ways
- Add the methods to the class on object instantiation
# frozen_string_literal: true
class Foo
def initialize(my_hsh = {})
my_hsh.each do |k, v|
self.class.define_method k do
v
end
end
end
end
hsh = {
first: 1,
second: 2,
}
my_foo = Foo.new(hsh)
puts my_foo.first
puts my_foo.second
this is not ideal, because if you create a second instance it will affect the first instance
e.g.
class Foo
def initialize(my_hsh = {})
my_hsh.each do |k, v|
self.class.define_method k do
v
end
end
end
end
hsh = {
first: 1,
second: 2,
}
hsh2 = {
first: 3,
second: 4,
}
my_foo = Foo.new(hsh)
Foo.new(hsh2)
puts my_foo.first # 3
puts my_foo.second # 4
alternatively you could make the methods dynamic by using method_missing
class Foo
def initialize(my_hsh = {})
@hsh = my_hsh
end
def method_missing(method)
@hsh[method] or raise NoMethodError.new("Method `#{method}` doesn't exist.")
end
end
hsh = {
first: 1,
second: 2,
}
hsh2 = {
first: 3,
second: 4,
}
my_foo = Foo.new(hsh)
Foo.new(hsh2)
puts my_foo.first # 1
puts my_foo.second # 2
puts my_foo.three # NoMethodError raised