From: Robert Klemme Date: 2010-07-31T19:07:33+09:00 Subject: Re: [].all?{} and [].any?{} Behavior 2010/7/30 Rick DeNatale : > On Thu, Jul 29, 2010 at 5:27 PM, John Sikora wrote: >> The second interesting thing is that a result of this behavior is that >> for the same check, all? will give a result of true, while any? will >> give a result of false. This seems contradictory. > > Well, there's a theoretical basis for this.  Enumeration#all? is an > implementation of the universal quantifier from predicate logic (that > upside down A) symbol. > > By convention the universal quantifier evaluates to true for an empty set: > http://en.wikipedia.org/wiki/Universal_quantification#The_empty_set > http://en.wikipedia.org/wiki/Vacuous_truth To complement this, De Morgan's Laws help do the conversion between all? and and? variants properly: http://en.wikipedia.org/wiki/De_Morgan%27s_laws >> I would prefer that for [], both all? and any? would give a result of >> false for any check. So I have over-ridden Array#all?, returning false >> if self == []. My main motivation for doing so is in situautions such >> as: >> >> obj_array.find_all{|obj| obj.attr_1 == x}.all?{|obj| obj.attr_2 == y} >> >> If the find_all returns [], I want the all? result to be false, not >> true. >> >> I assume that others have run across this but some quick searches did >> not turn up anything. I am wondering how others deal with this such as >> over-riding as I do, checking for [] each time (which does not seem very >> Ruby-like), or even leaving the operation as is because for some, it may >> be the desired behavior. >> >> Finally, are there any potential detrimental effects that might occur >> due to the behavior modification that I made. I am not a Rails user (if >> that matters), I mainly use Ruby for scripting and hardware control >> applications (and I am interested in learning as much as I can about >> Ruby because I like it so much). > > For your own usage as long as it doesn't mess up some other code you > are using, feel free. I disagree: IMHO it is a bad idea to change such fundamental behavior if only for own code. This opens the door widely for all sorts of bugs and issues. For example, you get used to #all? doing also the emptyness check and get confused when reading other code which of course relies on the regular behavior. Or you forget the "require" for the file that changes semantics of #all? and #any? and receive in turn subtly bugs which might be hard to track down. Even worse, you use library code that in turn uses #all? or #any? without you knowing it and this code suddenly breaks. > For library code, such as in a gem I think it would be better to think > up some other method name rather than changing the standard, e.g. That's definitively the way to go if the behavior should be put into a method. > module Enumerable >  def non_vacuous_all?(&b) >    !empty? && all?(&b) >  end > end > > [3].all? {|element| element == 3 }  # => true > [3].all? {|element| element != 3 }  # => false > > [].all? {|element| element == 3 }   # => true > [].all? {|element| element != 3 }   # => true > > [3].non_vacuous_all? {|element| element == 3 }  # => true > [3].non_vacuous_all? {|element| element != 3 }  # => false > > [].non_vacuous_all? {|element| element == 3 }   # => false > [].non_vacuous_all? {|element| element != 3 }   # => false > > [].any? {|element| element == 3 }   # => false > [].any? {|element| element != 3 }   # => false > > There may be a better name than non_vacuous_all? but I can't think of one. I'd rather stick with two method calls because it makes crystall clear what's happening. Also, you may first want to check for emptyness and if else branch based on that knowledge (or the other way round). In other words: often you may want to separate both checks. Kind regards robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/