Ruby: access to the caller in the method chain

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

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

Can I get a nil? result nil? but not what was for nil? input nil? .

I get:

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

Is it possible?

Note: this must be your own ruby no rails!

+4
source share
2 answers

You cannot achieve this.

s.nil? return value equal to either true or false , which are the only instances of TrueClass and FalseClass , respectively. You cannot create other instances of these two classes. Therefore, you cannot patch the monkey TrueClass or FalseClass remember the context s . You can define the singleton or method to true and false , however, it does not know anything about s , so you cannot associate 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 specified two helper methods.

Another thought is to return a customized object for all predicate methods (blabla?), Not true or false . However, in ruby ​​only nil and false give a lie, any other things give true. An instance of a personalized object will always be true, which will break all these predicate methods.

+1
source

try it

 p RUBY_VERSION ps = "" 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>' 

Above error due to s.nil? gives false and false - this is an instance of FalseClass , and this class has no or any method. therefore, the actual correction, as indicated above, I showed.

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 
0
source

All Articles