Ruby:在方法链中访问调用者

时间:2013-03-28 16:29:52

标签: ruby method-chaining

我正在尝试编写一个Or helper(基于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

这甚至可能吗?

注意:这需要原生红宝石 rails!

2 个答案:

答案 0 :(得分:1)

你无法做到这一点。

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

def true.or other
  true
end

def false.or other
  other
end

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

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

答案 1 :(得分:0)

试试这个

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?而导致falsefalseFalseClass的实例,而且此类没有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