こんばんは、Tsugohです。


先ほどから少し、指定したローカル変数だけを eval や ERb の中で
覗けるようには出来無いかと考えていました。

イメージとしては次のような感じで理解して頂けるでしょうか?

  estr = 'p [local_variables, foo, bar]'
  # 以降 estr は全て事前に定義されているものとします。
  
  eval2( estr ) { foo = 'foo'; bar = 100 }
  # stdout => [["foo", "bar"], "foo", 100]


ここまで奇麗(?)に出来無くても、似たようなことは出来無いかと考えた末に
次に様なコードが出来上がりました。

  def jail_binding
    binding
  end
  
  def eval2( estr, defval )
    jbin = jail_binding
    eval defval, jbin
    eval estr,   jbin
  end
  
  eval2 estr, %q{
    foo = 'foo'
    bar = 100
  }


ここで ERb にも応用するため、eval2 で使用している jbin を返すメソッドを作り
指定したローカル変数だけを閉じこめた binding を返すようにしたのですが、
文字列を使って変数定義している関係上、既に別の場所で定義されている
各種変数の中身を与えるのに次のようなコードになってしまいました。

  def closed_binding( defval )
    jbin = jail_binding  ## jail_binding も既に定義済みとします。
    eval defval, jbin
    jbin
  end
  
  baz = 'foo'
  qwe = 100
  
  new_binding = closed_binding %Q{
    foo = Marshal.load '#{Marshal.dump baz}'
    bar = Marshal.load '#{Marshal.dump qwe}'
  }


さすがに Marshal で二重に囲むのは奇麗ではないと思うため
なんとかしてみたいのですが、いまいち良いアイデアが思いつきません。
このままでは Marshal.dump 出来無いオブジェクトは代入できませんし。

実用性はあまりないので出来無くても別に構わないのですが、
もし可能ならどなたか教えて頂けないでしょうか?

よろしくお願いします。


# きっかけになったコードでは、Proc を使えば指定した以外のローカル変数や
# インスタンス変数が見える形で良ければ奇麗に作れるためそれを利用しています。
# 実用上は他の変数が見えても構いませんので。

# 何をもって「奇麗」とするかは人それぞれだということは理解していますので、
# その辺に関してのツッコミはご遠慮願います(^^;;;

-----
Tsugoh
mailto:tks / xxxx-xx.xx