Ruby 生成现有类的近亲类时“堆栈级别太深”
我正在为约束处理编写一个ruby模块 作为我的一点经验,主要是关于使用给定域实例化变量以及搜索和修剪 我的意图 约束实例将使用一组变量名和一个块进行初始化。将对块进行评估,以检查初始化是否满足约束 它的类方法Constraint.subclass返回Constraint的子类,比如subclass 1 在子类1中,有一个具有预定义块的初始值设定项(一个提供给Constraint.subclass的块)和一个类方法Subclass1.invert。后者通过再次使用Constraint.subclass返回约束的另一个子类,比如subclass 2 子类2中的预定义块应该是子类1中预定义块的反转版本 现状 这段代码或多或少符合我的意图。Constraint.subclass起作用,但subclass.invert似乎只有在预定义块具有确定的算术性时才起作用。否则会出现堆栈级别太深的情况Ruby 生成现有类的近亲类时“堆栈级别太深”,ruby,metaprogramming,stack-overflow,Ruby,Metaprogramming,Stack Overflow,我正在为约束处理编写一个ruby模块 作为我的一点经验,主要是关于使用给定域实例化变量以及搜索和修剪 我的意图 约束实例将使用一组变量名和一个块进行初始化。将对块进行评估,以检查初始化是否满足约束 它的类方法Constraint.subclass返回Constraint的子类,比如subclass 1 在子类1中,有一个具有预定义块的初始值设定项(一个提供给Constraint.subclass的块)和一个类方法Subclass1.invert。后者通过再次使用Constraint.subcla
#worked
EQ = Constraint.subclass {|a,b| a == b }
NE = EQ.invert
ALL_DISTINCT = Constraint.subclass {|*args| args.uniq.size == args.size}
#raised stackoverflow
HAVE_DUPLICATE = ALL_DISTINCT.invert
来源
在ruby1.9中列出了以下内容。省略了不太相关的方法,完整版本可在
您有单元测试来显示当前的工作方式吗?@OscarDelBen感谢您的提醒。令我惊讶的是,Constraint及其所有子类共享同一个类变量@@block。
module Solver
class Constraint # class method for a subclass
def self.subclass &block
Class.new(self) do
@@block = block
def initialize *args
super *args, &@@block
end
def self.invert # class method for a cousin class of current subclass
p "#{self}.invert"
new_block = proc {|*args| not @@block.call(*args)}
self.superclass.subclass &new_block
end
end
end
def initialize *vars, &block
# block will be substituted with variable in vars
raise ArgumentError "array of variable names is required"unless vars.is_a? Array
raise ArgumentError "block is expected" unless block_given?
@vars = vars.freeze
@proc = block.freeze
end
# less related methods
end
# predefined constraint schema
EQ = Constraint.subclass {|a,b| a == b }
NE = EQ.invert
GT = Constraint.subclass {|a,b| a > b }
NGT = GT.invert
LT = Constraint.subclass {|a,b| a < b }
NLT = LT.invert
ALL_DISTINCT = Constraint.subclass {|*args| args.uniq.size == args.size}
#HAVE_DUPLICATE = ALL_DISTINCT.invert
end