【问题标题】:Ruby: Accessing caller in method chainRuby:在方法链中访问调用者
【发布时间】:2013-03-28 16:29:52
【问题描述】:

我正在尝试编写 Or 助手(基于 Not Method by Jay Fields)。我想要实现的是:

s = ""
s.nil?             # false
s.empty?           # true
s.nil? || s.empty? # true
s.nil?.or.empty?   # should == true

我可以访问nil? 的结果,但不能访问nil? 的输入。

我明白了:

NoMethodError: undefined method `empty?' for false:FalseClass

这可能吗?

注意:这需要是原生 ruby​​ 而不是 rails!

【问题讨论】:

  • 我想我已经完成了,如果您有任何困惑,请查看答案并发表评论。

标签: ruby method-chaining


【解决方案1】:

你无法做到这一点。

s.nil? 的返回值为truefalse,它们分别是TrueClassFalseClass 的唯一实例。您不能创建这两个类的其他实例。所以你不能修改TrueClassFalseClass 来记住上下文s。您可以在truefalse 上定义单例方法or,但是,它对s 一无所知,因此您不能链接另一个谓词empty?

def true.or other
  true
end

def false.or other
  other
end

您可以编写s.nil?.or(s.empty?) 并定义两个辅助方法。

另一个想法是为所有谓词(blabla?)方法返回一个自定义对象,而不是truefalse。然而,在 ruby​​ 中,只有 nilfalse 产生 false,其他任何东西产生 true。您自定义对象的实例将始终为真,这将破坏所有这些谓词方法。

【讨论】:

    【解决方案2】:

    试试这个

    p RUBY_VERSION
    p s = ""
    p s.nil?             
    p s.empty?           
    p s.nil? || s.empty? 
    p (s.nil? or s.empty?)
    

    输出:

    "2.0.0"
    ""
    false
    true
    true
    true
    

    解释:

    s.nil?
    #=> false
    
    s.nil?.or.empty?
    #NoMethodError: undefined method `or' for false:FalseClass
    #        from (irb):5
    #        from C:/Ruby200/bin/irb:12:in `<main>'
    

    上面的错误是因为s.nil?给出了false,而falseFalseClass的一个实例,而这个类没有or方法。所以实际的修复如上所示。

    编辑

    p RUBY_VERSION
    class Object
    
    alias :oldnil :nil?
    
        def nil?
        @@x = self
        oldnil
        end
    end
    
    class FalseClass
        def or
        empty?
        end
    
        def empty?
        @@x.empty?
        end
    end
    
    class TrueClass
        def or
        empty?
        end
    
        def empty?
        @@x.empty?
        end
    end
    
    s = ""
    p s.nil?
    p s.empty?
    p s.nil? || s.empty?
    p s.nil?.or.empty?
    

    输出:

    "2.0.0"
    false
    true
    true
    true
    

    【讨论】:

    • 这仅适用于这种特定的条件组合。我认为 jamlen 对更通用的解决方案感兴趣。此外,它不是线程安全的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多