使用元编程对数字电路建模
Modeling a digital circuit using metaprogramming
我正在努力使用元编程为简单的数字电路系统建模。
想法是将 class 方法(例如 'input'、'output')添加到电路 class。每个新建模的电路(例如 Adder)都继承了 Circuit。在实例化这样一个电路时,我应该能够通过它的名称访问它的输入并获得相应的对象(一个 Input 实例)。让我们举例说明:
class Input
attr_accessor :name, :value
def initialize name
@name = name
@value=nil
end
end
class Circuit
def self.input name
send(:attr_accessor, name)
var_name = "@#{name}"
self.instance_variable_set(var_name, Input.new(name)) #no effect...
end
end
class Adder < Circuit
input :a
input :b
# output :f
end
p adder = Adder.new
p adder.a #Should be an Input instance, whose name attribute is :a
到目前为止,我只是成功地为指定端口动态添加了正确的访问器。
我应该使用 class_eval、instance_eval 还是 define_method?
您在错误的对象上调用 instance_variable_set
。您是在 class 本身上执行此操作,而应该在 class.
的新实例上执行此操作
像这样:
class Circuit
def self.input(name)
send(:attr_accessor, name)
# take note of this new input, we'll use it later
@_inputs ||= []
@_inputs << name
end
def initialize
# instantiate all defined inputs
self.class.instance_variable_get(:@_inputs).each do |name|
send("#{name}=", Input.new(name))
end
end
end
class Adder < Circuit
input :a
input :b
end
t = Adder.new
t.a # => #<Input:0x007f9664077ea0 @name=:a, @value=nil>
我正在努力使用元编程为简单的数字电路系统建模。
想法是将 class 方法(例如 'input'、'output')添加到电路 class。每个新建模的电路(例如 Adder)都继承了 Circuit。在实例化这样一个电路时,我应该能够通过它的名称访问它的输入并获得相应的对象(一个 Input 实例)。让我们举例说明:
class Input
attr_accessor :name, :value
def initialize name
@name = name
@value=nil
end
end
class Circuit
def self.input name
send(:attr_accessor, name)
var_name = "@#{name}"
self.instance_variable_set(var_name, Input.new(name)) #no effect...
end
end
class Adder < Circuit
input :a
input :b
# output :f
end
p adder = Adder.new
p adder.a #Should be an Input instance, whose name attribute is :a
到目前为止,我只是成功地为指定端口动态添加了正确的访问器。
我应该使用 class_eval、instance_eval 还是 define_method?
您在错误的对象上调用 instance_variable_set
。您是在 class 本身上执行此操作,而应该在 class.
像这样:
class Circuit
def self.input(name)
send(:attr_accessor, name)
# take note of this new input, we'll use it later
@_inputs ||= []
@_inputs << name
end
def initialize
# instantiate all defined inputs
self.class.instance_variable_get(:@_inputs).each do |name|
send("#{name}=", Input.new(name))
end
end
end
class Adder < Circuit
input :a
input :b
end
t = Adder.new
t.a # => #<Input:0x007f9664077ea0 @name=:a, @value=nil>