non vorrei lavorare

昔はおもにプログラミングやガジェット系、今は?

mrubyでselfを呼び出されたメソッドのインスタンスとして実行するには

こんばんは、GW中もどんどんいろいろなセリフを喋るように次男がなってきました。@kjunichiです。
 

背景

mrubyで画像変換処理を行うモジュールmruby-mrmagickを作り始めた。名前の通り、rmagickのAPIをmrubyで使えるように開発を進めている。そこで、今回の疑問にぶち当たった。Rmagickでは、処理の細かなオプションをブロックで指定するAPIになっており、

self.foo=bar

の形式で指定することになっていた。yieldで楽勝と思いきや、selfがyieldだと、メソッドのインスタンス変数とはならず、ブロック作成時の例えば、main等で実行されてしまうことがわかった。

mrubyでselfを呼び出されたメソッドのインスタンスとして実行するには

class Foo
  @width
  def mon(&blk)
    p self
    blk.call
  end
  def montage(&blk)
    instance_eval(&blk)
    p @width
  end

  attr_accessor :width
end

a=Foo.new
p a
p self
b=a.montage {
  p self
  self.width=100
}

instance_evalを使えば、意図した通りの動作になった。これで、mrmagickの開発が進むかも。

関連記事

 

9年前の記事

8年前の記事

3年前の記事

1年前の記事