【问题标题】:Metaprogramming with ruby, operator overloading and instance_eval使用 ruby​​、运算符重载和 instance_eval 进行元编程
【发布时间】:2012-04-30 04:47:06
【问题描述】:

例如我有这样的课:

class QueryDSL
  def initialize(&block)
    instance_eval &block
  end

  def ==(value)
    "bla bla '#{value}'"
  end

  def test(param)
    param + param
  end
end

和类查询类似:

class Query
  def self.where(&block)
    QueryDSL.new(&block)
  end
end

我怀疑执行时:

Query.where{test == 9}

输出应该是:

"bla bla 9 bla bla 9"

但我有例外:

`test': wrong number of arguments (0 for 1) (ArgumentError)

我的代码有什么错误吗?谢谢

【问题讨论】:

    标签: ruby closures metaprogramming block dsl


    【解决方案1】:

    您的问题是,当 QueryDSL#test 被定义为采用一个参数时,您正在调用不带参数的方法,因此

    `test': wrong number of arguments (0 for 1) (ArgumentError)
    

    错误。

    要么将 test 方法更改为不接受参数,要么为 param 设置默认值,或者在您的块中提供参数:

    Query.where { test(6) == 9 }
    

    尽管如此,这仍然不会调用您的 == 运算符,test 不会返回 QueryDSL 实例,因此无论它返回什么都将使用 == 运算符。

    【讨论】:

    • 参数测试是 (== 9) 的结果,其中是 bla bla 9。
    • @kav1nsky: 不,test== 之前被调用,所以你有 whatever_test_returns == 9 并且错误的 == 运算符将被使用,因为 test 不返回 QueryDSL 实例。
    • 但是当我调用 Query.where{ test test 9 } 结果是 36
    • test test 9test(test(9)) 相同,即9 + 9 + 9test == 9 就像 test() == 9test().==(9)
    • 有什么解释为什么方法调用是 test().==(9) 而不是 test(==(9))。谢谢
    猜你喜欢
    • 1970-01-01
    • 2016-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多