From: Josh Cheek on
[Note: parts of this message were removed to make it a legal post.]

What about redefining all? to accept an optional param for what to do when
empty? It doesn't change default behaviour, but lets you get your preferred
behaviour out of it. (note this only works on 1.9, because of how procs take
params in 1.8)


module Enumerable
old_all = instance_method(:all?)
define_method :all? do |emptyval=true,&block|
return emptyval if empty?
old_all.bind(self).call &block
end
end

require 'test/unit'

class NewAllTest < Test::Unit::TestCase
def test_empty
assert ![].all?(false)
assert [].all?(true)
assert [].all?
end
def test_non_empty_no_block
assert ![ nil, true, 99 ].all?(true)
assert ![ nil, true, 99 ].all?(false)
assert ![ nil, true, 99 ].all?
assert [ '', true, 99 ].all?(true)
assert [ '', true, 99 ].all?(false)
assert [ '', true, 99 ].all?
end
def test_non_empty_block
assert [ 1, 3, 99 ].all?( true , &:odd? )
assert [ 1, 3, 99 ].all?( false , &:odd? )
assert [ 1, 3, 99 ].all?( &:odd? )
assert ![ 1, 2, 99 ].all?( true , &:odd? )
assert ![ 1, 2, 99 ].all?( false , &:odd? )
assert ![ 1, 2, 99 ].all?( &:odd? )
end
def test_non_array
assert Hash[*1..10].all? { |key,value| key.odd? && value.even? }
end
end

From: David A. Black on
Hi --

On Tue, 3 Aug 2010, Josh Cheek wrote:

> What about redefining all? to accept an optional param for what to do when
> empty? It doesn't change default behaviour, but lets you get your preferred
> behaviour out of it. (note this only works on 1.9, because of how procs take
> params in 1.8)
>
>
> module Enumerable
> old_all = instance_method(:all?)
> define_method :all? do |emptyval=true,&block|
> return emptyval if empty?
> old_all.bind(self).call &block
> end
> end

You're working a bit too hard there; you can just do:

module Enumerable
alias old_all all?
def all?(emptyval=true, &block)
return emptyval if empty?
old_all(&block)
end
end

with no need for the round trip to the method object and back.

But I think overall it might be even easier just to call empty? :-) I'm
also not a fan of Boolean arguments. I never remember what they mean.


David

--
David A. Black, Senior Developer, Cyrus Innovation Inc.

The Ruby training with Black/Brown/McAnally
Compleat Philadelphia, PA, October 1-2, 2010
Rubyist http://www.compleatrubyist.com

From: Josh Cheek on
[Note: parts of this message were removed to make it a legal post.]

On Mon, Aug 2, 2010 at 5:12 PM, David A. Black <dblack(a)rubypal.com> wrote:

> Hi --
>
>
> On Tue, 3 Aug 2010, Josh Cheek wrote:
>
> What about redefining all? to accept an optional param for what to do when
>> empty? It doesn't change default behaviour, but lets you get your
>> preferred
>> behaviour out of it. (note this only works on 1.9, because of how procs
>> take
>> params in 1.8)
>>
>>
>> module Enumerable
>> old_all = instance_method(:all?)
>> define_method :all? do |emptyval=true,&block|
>> return emptyval if empty?
>> old_all.bind(self).call &block
>> end
>> end
>>
>
> You're working a bit too hard there; you can just do:
>
> module Enumerable
> alias old_all all?
> def all?(emptyval=true, &block)
> return emptyval if empty?
> old_all(&block)
> end
> end
>
> with no need for the round trip to the method object and back.
>
> But I think overall it might be even easier just to call empty? :-) I'm
> also not a fan of Boolean arguments. I never remember what they mean.
>
>
>
> David
>
> --
> David A. Black, Senior Developer, Cyrus Innovation Inc.
>
> The Ruby training with Black/Brown/McAnally
> Compleat Philadelphia, PA, October 1-2, 2010
> Rubyist http://www.compleatrubyist.com
>
>
I did it that way based on the observations at this blog
http://blog.jayfields.com/2006/12/ruby-alias-method-alternative.html but I
guess if you're working by yourself, you will know you did it and not have
collision issues, and if you're working with a team, you would probably not
be redefining Enumerable#all? so alias is probably a much better choice.

From: David A. Black on
Hi --

On Tue, 3 Aug 2010, Josh Cheek wrote:

> On Mon, Aug 2, 2010 at 5:12 PM, David A. Black <dblack(a)rubypal.com> wrote:
>
>> Hi --
>>
>>
>> On Tue, 3 Aug 2010, Josh Cheek wrote:
>>
>> What about redefining all? to accept an optional param for what to do when
>>> empty? It doesn't change default behaviour, but lets you get your
>>> preferred
>>> behaviour out of it. (note this only works on 1.9, because of how procs
>>> take
>>> params in 1.8)
>>>
>>>
>>> module Enumerable
>>> old_all = instance_method(:all?)
>>> define_method :all? do |emptyval=true,&block|
>>> return emptyval if empty?
>>> old_all.bind(self).call &block
>>> end
>>> end
>>>
>>
>> You're working a bit too hard there; you can just do:
>>
>> module Enumerable
>> alias old_all all?
>> def all?(emptyval=true, &block)
>> return emptyval if empty?
>> old_all(&block)
>> end
>> end
>>
>> with no need for the round trip to the method object and back.
>>
>> But I think overall it might be even easier just to call empty? :-) I'm
>> also not a fan of Boolean arguments. I never remember what they mean.
>>
> I did it that way based on the observations at this blog
> http://blog.jayfields.com/2006/12/ruby-alias-method-alternative.html but I
> guess if you're working by yourself, you will know you did it and not have
> collision issues, and if you're working with a team, you would probably not
> be redefining Enumerable#all? so alias is probably a much better choice.

The blog post makes the motivation clearer to me -- thanks. The
Enumerable#all example is (I hope :-) just hypothetical; I definitely
wouldn't advocate overriding it at all.


David

--
David A. Black, Senior Developer, Cyrus Innovation Inc.

The Ruby training with Black/Brown/McAnally
Compleat Philadelphia, PA, October 1-2, 2010
Rubyist http://www.compleatrubyist.com