市田です。

On 2017/02/03 18:12, yamataka / u08.itscom.net wrote:
> class Ika
>   def initialize
>     @api_name_list = self.getSupportedApiInfo
>   end
>
>   @api_name_list.each do |apiname|
>     define_method(apiname){ puts "#{apiname}" }
>   end
>
>   def getSupportedApiInfo
>     Array['setPowerSettings','getStorageList']
>   end
> end
> Ika.new.setPowerSettings # ./tako.rb:15:in `<class:Ika>': undefined
> method `each' for nil:NilClass (NoMethodError) from ./tako.rb:10:in `<
> main>'
>
> define_method する前に、そもそも、@api_name_list が nil だという事で、実
> 行時エラーになってしまいます。
> この様な感じで、define_method で method 定義は出来ないのでしょうか?
> ご教示お願いします。

define_method のレシーバが何かを考えると、nilに
なるのと、define_method がうまくいかないのとが
理解できるのではと思います。

@api_name_list はどちらもインスタンス変数ですが、
それぞれ別のものを指しています。

最初のものはIkaオブジェクトのインスタンス変数を、
後者はIkaクラスオブジェクトのインスタンス変数を
参照するという違いがあるので、別もののため、nil
になります。

irb(main):001:0> class Foo
irb(main):002:1>   @var = 1
irb(main):003:1>   def make
irb(main):004:2>     @var = 2
irb(main):005:2>   end
irb(main):006:1> end
=> :make
irb(main):007:0> obj = Foo.new
=> #<Foo:0x33f79b0>
irb(main):008:0> obj.make
=> 2 # Fooオブジェクトのインスタンス変数 @var
irb(main):009:0> Foo.instance_variable_get(:@var)
=> 1 # Foo*クラス* オブジェクトのインスタンス変数 @var
irb(main):011:0>

そもそも define_method が呼ばれる「クラスの定義を
実行している」ときには、まだ initialize は呼ばれて
いないというのもあります。

initialize メソッドの中でメソッド定義するなら
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/437447
の方法が使えるのではと思います。

ただそのスレッドの別のポストにもありますが、
- 素直にオブジェクトの特異メソッドを def で定義する
- オブジェクトもしくはクラスで extend する
のが良いのでは?

このあたりは『メタプログラミングRuby』が参考になります。

ではでは。




>
>
>