なぜかRubyの勉強を再開しました。
さてさて。RubyにはKernel.eval
という命令があり、任意のRubyのコードを実行できる仕組みが備わっていることを知りました。
ということは、ループでぐるぐる回せば色んなことができんじゃね?ということで、まずは前々からやってみたかった、複数のインスタンスを一気に作成するコードを書いてみました。
ソースコード
sample_code.rb
#!/usr/local/opt/ruby/bin/ruby
class HelloWorld
def initialize(name)
@name = name
end
def sayHello
puts @name << ", Hello."
end
attr_accessor :name
end
# 対象になるのはBobとTomとJerry
name_array = ["Bob", "Tom", "Jerry"]
# インスタンスの作成
name_array.each do |name|
var = "@new_" << name
value = "HelloWorld.new('#{name}')"
eval("#{var} = #{value}") # @new_Bob = HelloWorld.new('Bob')
end
# インスタンスメソッドの呼び出し
name_array.each do |name|
code = "@new_" << name << ".sayHello"
eval(code) # @new_Bob.sayHello
end
出力結果
terminal
[21:50] archinwater % ./test2.rb
Bob, Hello.
Tom, Hello.
Jerry, Hello
ハマりどころ
- evalの中での変数のスコープがややこしい(上記ソースコードで、オブジェクト変数をインスタンス変数にしているが、仮にローカル変数を使うと、後々そのオブジェクトを参照出来なくなる)
- evalの引数はstring(まずは)。
eval("#{var} = #{value}")
は通るけど、eval(#{var} = #{value})
は通らない。