"堆叠水平太深"当生成现有类的表兄类时

时间:2012-06-06 14:45:23

标签: ruby metaprogramming stack-overflow

我正在编写一个用于约束处理的ruby模块。

(正如我的经验,主要是关于使用给定域和搜索和修剪来实现变量的实现)

我的意图

Constraint的实例将使用一组变量名和一个块进行初始化。将评估该块以检查初始化是否满足约束。

使用一个块,它的类方法Constraint.subclass返回Constraint的子类,比如Subclass1

Subclass1中,有一个带有预定义块的初始化器(一个被馈送到Constraint.subclass)和一个类方法Subclass1.invert。后者再次使用Constraint返回Subclass2的另一个子类,比如Constraint.subclass

Subclass2中的预定义块应该是Subclass1

中的预定义块的反转版本

现状

代码或多或少按我的意图行事。 Constraint.subclass有效,但似乎Subclass.invert仅在预定义块具有确定性时才起作用。否则stack level too deep将会出现。

#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中的

。省略了较少的核心方法,https://gist.github.com/2882291

提供完整版本
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

0 个答案:

没有答案