Ruby中的元编程错误
好吧,这让我发疯了。这段代码的要点是,我应该能够动态添加一个方法,只要它的形式是object.plusnum,其中num是任意数字。我不太清楚如何让它工作。这是我迄今为止最好的一次尝试,但我目前遇到了几个错误 代码: 我目前遇到的错误是“class_eval”未定义。我对元编程和ruby相当陌生,这让我发疯Ruby中的元编程错误,ruby,metaprogramming,Ruby,Metaprogramming,好吧,这让我发疯了。这段代码的要点是,我应该能够动态添加一个方法,只要它的形式是object.plusnum,其中num是任意数字。我不太清楚如何让它工作。这是我迄今为止最好的一次尝试,但我目前遇到了几个错误 代码: 我目前遇到的错误是“class_eval”未定义。我对元编程和ruby相当陌生,这让我发疯 您必须在Adder类上调用class\u eval,而不是在Adder实例上调用 该字符串无效。在#{method}后面加括号 新版本的代码: class Adder def initial
Adder
类上调用class\u eval
,而不是在Adder实例上调用#{method}
后面加括号class Adder
def initialize(_val)
@start_value = _val
end
def method_missing(method_name, *args)
method = method_name.to_s
if method.start_with?("plus") then
num = method[4 .. method.length]
if (/^[\d]+(\.[\d]+){0,1}$/ === num) then
number = Integer(num)
self.class.class_eval("def #{method}() return @start_value + #{number} end")
else
super
end
else
super
end
end
end
a = Adder.new(0)
a.plus1
就我自己而言,我建立这种方法的方法只是从
class Adder
end
Adder.class_eval("def plus1() return 0 + 1 end")
a = Adder.new
a.plus1
然后逐渐用可配置的值替换硬连接的值,而不是一次写入所有内容
class Adder
def initialize(_val)
@start_value = _val
end
def method_missing(method_name, *args)
method = method_name.to_s
if method.start_with?("plus") then
num = method[4 .. method.length]
if (/^[\d]+(\.[\d]+){0,1}$/ === num) then
number = Integer(num)
self.class.class_eval("def #{method}() return @start_value + #{number} end")
eval(method)
else
super
end
else
super
end
end
end
a = Adder.new(0)
a.plus1
Adder
类上调用class\u eval
,而不是在Adder实例上调用#{method}
后面加括号class Adder
def initialize(_val)
@start_value = _val
end
def method_missing(method_name, *args)
method = method_name.to_s
if method.start_with?("plus") then
num = method[4 .. method.length]
if (/^[\d]+(\.[\d]+){0,1}$/ === num) then
number = Integer(num)
self.class.class_eval("def #{method}() return @start_value + #{number} end")
else
super
end
else
super
end
end
end
a = Adder.new(0)
a.plus1
就我自己而言,我建立这种方法的方法只是从
class Adder
end
Adder.class_eval("def plus1() return 0 + 1 end")
a = Adder.new
a.plus1
然后逐渐用可配置的值替换硬连接的值,而不是一次写入所有内容
class Adder
def initialize(_val)
@start_value = _val
end
def method_missing(method_name, *args)
method = method_name.to_s
if method.start_with?("plus") then
num = method[4 .. method.length]
if (/^[\d]+(\.[\d]+){0,1}$/ === num) then
number = Integer(num)
self.class.class_eval("def #{method}() return @start_value + #{number} end")
eval(method)
else
super
end
else
super
end
end
end
a = Adder.new(0)
a.plus1
确保在最后添加eval(method)以调用该方法,否则仅创建该方法时它将返回nil。或者您可以使用return@start_value+#{number}简单返回
确保在最后添加eval(method)以调用该方法,否则仅创建该方法时它将返回nil。或者您可以使用return@start_value+#{number}简单地返回 第一次调用一个方法会产生与第二次调用不同的结果,因此您可能希望在定义后立即调用该方法。另外--您正在使用相当复杂的正则表达式,然后将值转换为
整数
,并删除点后面的所有数字
您正在使用class\u eval
并向其传递字符串,这通常是个坏主意,出于安全和性能原因,应该尽可能使用block
我怎么看呢
class Adder
def initialize(val)
@start_value = val
end
def method_missing(method_name, *args)
if method_name.to_s =~ /^plus(\d+)$/
self.class.class_eval do
define_method(method_name) { @start_value + $1.to_i }
end
self.send(method_name)
else
super
end
end
end
我想你全搞错了:) 第一次调用一个方法会产生与第二次调用不同的结果,因此您可能希望在定义后立即调用该方法。另外--您正在使用相当复杂的正则表达式,然后将值转换为
整数
,并删除点后面的所有数字
您正在使用class\u eval
并向其传递字符串,这通常是个坏主意,出于安全和性能原因,应该尽可能使用block
我怎么看呢
class Adder
def initialize(val)
@start_value = val
end
def method_missing(method_name, *args)
if method_name.to_s =~ /^plus(\d+)$/
self.class.class_eval do
define_method(method_name) { @start_value + $1.to_i }
end
self.send(method_name)
else
super
end
end
end