# Re: Symbol#to\_proc is just so beautiful

**URL:** <https://www.ruby-forum.com/t/re-symbol-to-proc-is-just-so-beautiful/94060>\
**Category:** Ruby\
**Created:** [April 19, 2006, 6:36pm UTC](https://www.ruby-forum.com/t/re-symbol-to-proc-is-just-so-beautiful/94060 "2006-04-19T18:36:24Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![BergerS\_Daniel](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/bc8723/32.png) [@BergerS\_Daniel](https://www.ruby-forum.com/u/BergerS_Daniel)\
**Post date:** [April 19, 2006, 6:36pm UTC](https://www.ruby-forum.com/t/re-symbol-to-proc-is-just-so-beautiful/94060/1 "2006-04-19T18:36:24Z")

</div>

> ```
> def to_proc
> 
> ```
> 
> end
> 
> [1, 2, 3].all? &:positive? =\> true  
> [-1, 2, 3].all? &:positive? =\> false
> 
> It’s just so damn beautiful!

There must be a way to ditch that ‘&’ somehow. I’d prefer this:

[1,2,3].all?(:positive?)

Dan

---

<div class="post-metadata">

**Author:** ![BergerS\_Daniel](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/bc8723/32.png) [@BergerS\_Daniel](https://www.ruby-forum.com/u/BergerS_Daniel)\
**Post date:** [April 19, 2006, 7:32pm UTC](https://www.ruby-forum.com/t/re-symbol-to-proc-is-just-so-beautiful/94060/2 "2006-04-19T19:32:31Z")

</div>

On 4/19/06, Berger, Daniel [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > 
> 
> There must be a way to ditch that ‘&’ somehow. I’d prefer this:
> 
> [1,2,3].all?(:positive?)

It’s possible be adjusting the definition of Enumerable#all?

$ cat test.rb  
class Symbol  
def to\_proc  
proc{ |obj| obj.send(self) }  
end  
end

module Enumerable  
alias :old\_all? :all?

```
def all?(non_block=nil, &block)
  if non_block
    if block.nil? and non_block.respond_to?(:to_proc)
      block = non_block.to_proc
    else
      raise ArgumentError
    end
  end
  old_all? &block
end

```

end

class Numeric  
def positive?  
self \> 0  
end

```
def even?
  (self % 2).zero?
end

```

end

puts [1, 2, 3].all?  
puts [1, 2, 3].all? { |i| i \< 4 }  
puts [1, 2, 3].all? { |i| i \> 2 }  
puts [1, 2, 3].all?( :positive? )  
puts [1, 2, 3].all?( :even? )

$ ruby test.rb  
true  
true  
false  
true  
false

I’m not sure if there’s anyway to do it without redefining the target  
function, however.

Jacob F.

---

<div class="post-metadata">

**Author:** ![BergerS\_Daniel](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/bc8723/32.png) [@BergerS\_Daniel](https://www.ruby-forum.com/u/BergerS_Daniel)\
**Post date:** [April 19, 2006, 8:43pm UTC](https://www.ruby-forum.com/t/re-symbol-to-proc-is-just-so-beautiful/94060/3 "2006-04-19T20:43:56Z")

</div>

Berger, Daniel wrote:

> > [1, 2, 3].all? &:positive? =\> true  
> > [-1, 2, 3].all? &:positive? =\> false  
> > There must be a way to ditch that ‘&’ somehow. I’d prefer this:  
> > [1,2,3].all?(:positive?)

The beauty of Symbol#to\_proc is that you don’t need to change any method  
definitions for it to work; any method that yields a single argument can  
take a symbol proc as a block, and it’ll work out of the box.

arr.any? &:positive?  
arr.none? &:positive?  
arr.each(&:upcase!)  
arr.collect(&:downcase)

Daniel

---

<div class="post-metadata">

**Author:** ![BergerS\_Daniel](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/bc8723/32.png) [@BergerS\_Daniel](https://www.ruby-forum.com/u/BergerS_Daniel)\
**Post date:** [April 19, 2006, 9:15pm UTC](https://www.ruby-forum.com/t/re-symbol-to-proc-is-just-so-beautiful/94060/4 "2006-04-19T21:15:14Z")

</div>

2006/4/19, Daniel S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> arr.any? &:positive?  
> arr.none? &:positive?  
> arr.each(&:upcase!)  
> arr.collect(&:downcase)

An approach similar to Facets’ Enumerable#every would look better

arry.any?.positive?  
arr.none?.positive?  
arr.each.upcase!  
arry.collect.downcase # arry.every.downcase

But it would require modification of all those methods, like Jacob  
says. It is worthwhile, in my opinion.

–  
Gerardo S.  
“Between individuals, as between nations, respect for the rights of  
others is peace” - Don Benito Juárez

> **[Santana's Tech Notes](http://santanatechnotes.blogspot.com/)**
>
> Small notes about technical related stuff I do, mainly OpenBSD and Ruby

---

<div class="post-metadata">

**Author:** ![BergerS\_Daniel](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/bc8723/32.png) [@BergerS\_Daniel](https://www.ruby-forum.com/u/BergerS_Daniel)\
**Post date:** [April 19, 2006, 9:24pm UTC](https://www.ruby-forum.com/t/re-symbol-to-proc-is-just-so-beautiful/94060/5 "2006-04-19T21:24:36Z")

</div>

Gerardo S. Gómez Garrido wrote:

> An approach similar to Facets’ Enumerable#every would look better
> 
> arry.any?.positive?  
> arr.none?.positive?

These already have another meaning in 1.8. any?() without a block  
returns true if any of the elements is a true value.

> arr.each.upcase!  
> arry.collect.downcase # arry.every.downcase

These will have another meaning in 1.9. each() and collect() without a  
block will return enumerators.

---

<div class="post-metadata">

**Author:** ![BergerS\_Daniel](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/bc8723/32.png) [@BergerS\_Daniel](https://www.ruby-forum.com/u/BergerS_Daniel)\
**Post date:** [June 30, 2006, 11:06am UTC](https://www.ruby-forum.com/t/re-symbol-to-proc-is-just-so-beautiful/94060/6 "2006-06-30T11:06:42Z")

</div>

Berger, Daniel wrote:

> There must be a way to ditch that ‘&’ somehow. I’d prefer this:
> 
> [1,2,3].all?(:positive?)

What you are suggesting is basically an expansion of something that was  
suggested in RCR50 and rejected.  
([RCRS](http://www.rcrchive.net/rejected.html#rcr50))

I like the idea too. It would be even better if you could also pass  
parameters along.

Here are a few more examples:

[1,2,3].any?(:\>, 4)

[1,2,3].map(:\*, 4) #-\> [4,8,12]

people.collect(:name)

people.select(:retired?)

people.sort\_by(:age)

favorite\_numbers.select(:between?, 100,200)

people.each(:give\_compensation, 50)

Here’s the implementation:

# enumerable-rcr50.rb

class Array

```
enumerable_methods = [:each,:select, :find_all, :map, :collect, 

```

:any?, :all?,  
:sort\_by, :reject, :detect, :find, :find\_all]  
# max\_by, min\_by, partition\_by can be added in  
Ruby 1.9  
for method\_name in enumerable\_methods  
old\_method\_name = “old\_” + method\_name.to\_s  
module\_eval %Q{  
alias\_method :#{old\_method\_name}, :#{method\_name}  
def #{method\_name}(message = nil, \*args, &block)  
block ||= Proc.new { |e| e.send(message, \*args) }  
if message or block\_given?  
#{old\_method\_name}(&block)  
else # method was called without passing any  
parameters, nor a block  
#{old\_method\_name}  
end  
end  
}  
end

```
alias_method(:do, :each)
alias_method(:in_order_of, :sort)

```

end

Basically, if the callers passes a block, the original method is called.  
If he specifies a message and some arguements, they are converted into a  
block and passed to the original method. If he gives both, the block is  
used and the message is ignored. If neither is given (as in:  
[1,2,3].map), the original method is called with no parameters.

Take note that :detect (and its alias :find) accept an additional  
parameter (representing what should be returned if nothing is found), so  
changing them WILL break existing code.

Now, I need help. As you may notice - the above only extends Array. If  
you change “class Array” to “module Enumerable” in the above code, it  
turns out that Ruby (1.8.4) refuses to let you override methods such as  
map, while at the same time, “any?” and “all?” work fine. Anyone got a  
clue as to how I could fix this?

P.S. for other approaches to this problem, see the Higher Order  
Messaging in Ruby articles by Nat Pyrce  
([http://nat.truemesh.com/archives/000535.html](http://nat.truemesh.com/archives/000535.html)), the Junction library,  
and Ruby F.s.

---

<div class="post-metadata">

**Author:** ![BergerS\_Daniel](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/bc8723/32.png) [@BergerS\_Daniel](https://www.ruby-forum.com/u/BergerS_Daniel)\
**Post date:** [June 30, 2006, 1:53pm UTC](https://www.ruby-forum.com/t/re-symbol-to-proc-is-just-so-beautiful/94060/7 "2006-06-30T13:53:53Z")

</div>

Omer Raviv wrote:

> suggested in RCR50 and rejected.  
> ([RCRS](http://www.rcrchive.net/rejected.html#rcr50))

Heh, I’d forgotten it was ever suggested before.

> 

Here’s my implementation for Array#map.

class Array  
def map(\*args)  
array = []  
hash = {}  
current = nil  
args.each{ |arg|  
if arg.is\_a?(Symbol)  
hash[arg] = []  
current = arg  
else  
hash[current] \<\< arg  
end  
}

```
  self.each{ |e|
     hash.each{ |m, params|
        unless params.empty?
           e = e.send(m, *params)
        else
           e = e.send(m)
        end
     }
     yield e if block_given?
     array << e
  }

  array

```

end  
end

(Logan C. refactored this somewhat)

> Now, I need help. As you may notice - the above only extends Array. If  
> you change “class Array” to “module Enumerable” in the above code, it  
> turns out that Ruby (1.8.4) refuses to let you override methods such as  
> map, while at the same time, “any?” and “all?” work fine. Anyone got a  
> clue as to how I could fix this?

Array#map is overridden in array.c, so modifying it in Enumerable won’t  
affect Array.

Regards,

Dan
