From: ptkwt@... (Phil Tomson) Date: 2006-02-11T05:43:23+09:00 Subject: rebinding a Proc Weird stuff ahead. I'm making (actually, remaking) a DSL. I'm re-visioning RHDL to take more advantage of metaprogramming tricks. So I'd like the user to be able to declare a logic gate like so: class AndGate < RHDL inputs :a, :b inouts :bus outputs :a_and_b define_behavior { puts "Inside of define_behavior: a is: #{a}, b is: #{b}" a_and_b = a & b } end And then the user should be able to instantiate an AndGate like so: andg = AndGate.instance() #optional args The 'inputs', 'inouts' and 'outputs' methods create accessors for the signals at the class level so that they are then accessable in the block passed to define_behavior. Here's some of the background from the RHDL class: class RHDL class << self def instance(*args) #clones this class. puts "instance:self is: #{self}" klass = self.clone puts "klass.class is: #{klass.class}" klass end def define_behavior(&b) @__behavior = b puts "@behavior.class is: #{@__behavior.class}" end def behavior @__behavior end def run puts "in #{self}::run" puts "a is: #{a}, b is: #{b} " @__behavior.call end def inports @__inports ||=[] end def inoutports @__inoutports ||=[] end def outports @__outports ||=[] end def create_accessor str instance_eval "def #{str}=(val); puts \"self is: #{self}\"; @#{str} = val; end" instance_eval "def #{str}; @#{str} ||=0; end" end def inputs *in_syms in_syms.each {|input| inports << Port.new(input.to_s) create_accessor input } end #... outputs, inouts, etc. end Of course, the problem is in the block passed to the define_behavior method. It's defined within the context of the AndGate class definition above, so if we clone the AndGate class itself we find that the behavior is still determined by the context of the original AndGate class. So If I do: AndGate.a=1; AndGate.b=1 AndGate.run #=> 1 a = AndGate.instance() a.a=0; a.b=0 a.run #=> 1 (but should be 0; this is because the block is still evaluated in the context of AndGate class, not the clone of AndGate) So when the AndGate class is cloned, is there a way to unbind the proc in the class' @__behavior class inst var and rebind it in the context of the new cloned class? (kind of what can be done with methods and UnboundMethod) [I realize there are probably other ways to do this where this wouldn't be an issue (use a method instead of a proc, for example) but I'm trying to maintain compatibility with the backend simulation guts of the current RHDL system.] Phil