Pergunta

I am trying to write an Or helper (based upon Not Method by Jay Fields). What I am trying to achieve is:

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

I can access the result of nil? but not what the input to nil? was.

I get:

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

Is this even possible?

Note: this needs to be native ruby not rails!

Foi útil?

Solução

You cannot achieve this.

The return value of s.nil? is either true or false, which are the only instances of TrueClass and FalseClass, respectively. You cannot create other instances of the two classes. So you cannot monkey patch TrueClass or FalseClass to remember the context s. You can define singleton method or on true and false, however, it knows nothing about s so you cannot chain another predicate empty?.

def true.or other
  true
end

def false.or other
  other
end

You can write s.nil?.or(s.empty?) with the two helper method defined.

Another thought is to return a customized object for all predicate (blabla?) methods, rather than true or false. However, in ruby, only nil and false yield false, any other stuffs yield true. You instance of the customized object will always be true, which will break all those predicate methods.

Outras dicas

try this

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

Output:

"2.0.0"
""
false
true
true
true

Explanation:

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>'

The above error because of s.nil? gives false and false is an instance of FalseClass, and this class don't have or method any. so actual fix is as above I have shown.

EDIT:

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?

Output:

"2.0.0"
false
true
true
true
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top