Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > idiom I've not seen before

Reply
Thread Tools

idiom I've not seen before

 
 
Rob Saul
Guest
Posts: n/a
 
      02-07-2008

I came across this :
elements.sort_by(&osition).each
in something I've taken over. I thought sort_by
took a block. Obviously I'm missing something.
Can anyone shed some light on this trick?

~Rob


 
Reply With Quote
 
 
 
 
Rob Biedenharn
Guest
Posts: n/a
 
      02-07-2008
On Feb 6, 2008, at 10:55 PM, Rob Saul wrote:
> I came across this :
> elements.sort_by(&osition).each
> in something I've taken over. I thought sort_by
> took a block. Obviously I'm missing something.
> Can anyone shed some light on this trick?
>
> ~Rob



You've found Symbol#to_proc

That line is equivalent to:

elements.sort_by {|e| e.send(osition) }.each

The "something" is a Rails project, isn't it?

== vendor/rails/activesupport/lib/active_support/core_ext/symbol.rb ==
class Symbol
# Turns the symbol into a simple proc, which is especially useful
for enumerations. Examples:
#
# # The same as people.collect { |p| p.name }
# people.collect(&:name)
#
# # The same as people.select { |p| p.manager? }.collect { |p|
p.salary }
# people.select(&:manager?).collect(&:salary)
def to_proc
Proc.new { |*args| args.shift.__send__(self, *args) }
end
end


I don't know how you can send additional arguments however.

-Rob

Rob Biedenharn http://agileconsultingllc.com




 
Reply With Quote
 
 
 
 
Jeremy Kemper
Guest
Posts: n/a
 
      02-07-2008
On 2/6/08, Rob Saul <> wrote:
> I came across this :
> elements.sort_by(&osition).each
> in something I've taken over. I thought sort_by
> took a block. Obviously I'm missing something.
> Can anyone shed some light on this trick?


Sure. &osition == osition.to_proc == proc { |element, *args|
element.position(*args) }

So elements.sort_by(&osition) is shorthand for sorting the elements
by position.

jeremy

 
Reply With Quote
 
Rob Saul
Guest
Posts: n/a
 
      02-07-2008
Jeremy Kemper wrote:
>
> Sure. &osition == osition.to_proc == proc { |element, *args|
> element.position(*args) }
>
> So elements.sort_by(&osition) is shorthand for sorting the elements
> by position.
>
> jeremy


thanks to both Jeremy and Rob for the enlightenment. And
yes, it is a Rails project.



 
Reply With Quote
 
Martin DeMello
Guest
Posts: n/a
 
      02-07-2008
On Feb 7, 2008 4:14 AM, Rob Saul <> wrote:

> thanks to both Jeremy and Rob for the enlightenment. And
> yes, it is a Rails project.


Also, I believe Symbol.to_proc is making it into 1.9

martin

 
Reply With Quote
 
Thomas Wieczorek
Guest
Posts: n/a
 
      02-07-2008
On Thu, Feb 7, 2008 at 6:04 AM, Martin DeMello <> wrote:
>
> Also, I believe Symbol.to_proc is making it into 1.9
>


Yes, it is in.
Raganwald has a good blog entry about it, he also mentions
String#to_proc:
http://weblog.raganwald.com/2007/11/...boltoproc.html

 
Reply With Quote
 
Ryan Davis
Guest
Posts: n/a
 
      02-07-2008

On Feb 6, 2008, at 20:04 , Rob Biedenharn wrote:

> You've found Symbol#to_proc
>
> That line is equivalent to:
>
> elements.sort_by {|e| e.send(osition) }.each


Buyer beware:

#!/usr/local/bin/ruby -w

# # of iterations = 10000
# user system total real
# null_time 0.000000 0.000000 0.000000 ( 0.001561)
# map 0.880000 0.000000 0.880000 ( 0.878500)
# to_proc 2.790000 0.000000 2.790000 ( 2.799291)

# # of iterations = 100000
# user system total real
# null_time 0.020000 0.000000 0.020000 ( 0.013951)
# map 8.730000 0.010000 8.740000 ( 8.766693)
# to_proc 27.960000 0.030000 27.990000 ( 28.00128

require 'benchmark'

class Symbol
def to_proc
Proc.new { |*args| args.shift.__send__(self, *args) }
end
end

a = (1..100).to_a

raise "stupid" unless a.map { |n| n.to_s } == a.map(&:to_s)

max = (ARGV.shift || 1_000_000).to_i

puts "# of iterations = #{max}"
Benchmark::bm(20) do |x|
x.report("null_time") do
for i in 0..max do
# do nothing
end
end

x.report("map") do
for i in 0..max do
a.map { |n| n.to_s }
end
end

x.report("to_proc") do
for i in 0..max do
a.map(&:to_s)
end
end
end


 
Reply With Quote
 
botp
Guest
Posts: n/a
 
      02-07-2008
On Feb 7, 2008 1:16 PM, Ryan Davis <ryand-> wrote:
>
> Buyer beware:
>
> # # of iterations = 10000
> # user system total real
> # null_time 0.000000 0.000000 0.000000 ( 0.001561)
> # map 0.880000 0.000000 0.880000 ( 0.878500)
> # to_proc 2.790000 0.000000 2.790000 ( 2.799291)
>
> # # of iterations = 100000
> # user system total real
> # null_time 0.020000 0.000000 0.020000 ( 0.013951)
> # map 8.730000 0.010000 8.740000 ( 8.766693)
> # to_proc 27.960000 0.030000 27.990000 ( 28.00128


that will change in ruby1.9 since to_proc is builtin.
eg, a run in windows,

C:\ruby1.9\bin>.\ruby.exe test.rb 1_000
# of iterations = 1000
user system total real
null_time 0.000000 0.000000 0.000000 ( 0.000000)
map 0.203000 0.000000 0.203000 ( 0.203000)
to_proc 0.156000 0.000000 0.156000 ( 0.172000)

C:\ruby1.9\bin>.\ruby.exe test.rb 10_000
# of iterations = 10000
user system total real
null_time 0.016000 0.000000 0.016000 ( 0.015000)
map 1.937000 0.000000 1.937000 ( 2.515000)
to_proc 1.610000 0.000000 1.610000 ( 1.954000)

C:\ruby1.9\bin>.\ruby.exe test.rb 100_000
# of iterations = 100000
user system total real
null_time 0.328000 0.000000 0.328000 ( 0.328000)
map 19.344000 0.000000 19.344000 ( 24.953000)
to_proc 17.296000 0.015000 17.311000 ( 18.016000)

not bad, imho.
kind regards -botp

 
Reply With Quote
 
Phrogz
Guest
Posts: n/a
 
      02-07-2008
On Feb 6, 8:55 pm, Rob Saul <w...@code-gnomemad.org> wrote:
> I came across this :
> elements.sort_by(&osition).each


Loosely-related aside:

I've been learning Io[1] recently. Io (like Lisp, I gather) allows
lazy evaluation of method arguments. In Ruby terms, this would mean
that I can write something like this:

# Ruby-esque pseudo-code; neither Io nor Ruby
class Array
def select
result = []
self.each{ |el| result << el if el.sendArg(0) }
result
end
end

my_array.select( isCool? )
my_array.select( > 5 )
my_array.select( roughlyEquals( jim.newSize ) )

In Io, the "isCool?" method/message isn't (necessarily) evaluated when
you call the select method. Instead, you can perform some
introspection on the parsed message tree for each argument and choose
to ignore it, change it to a string, or send it as a message to any
object you want.

To be clear, in the above, the "isCool?" message/method would be send/
invoked on each array element. Or each element would be sent a
">( 5 )" message.

The Symbol#to_proc technique is clever, but not quite as clean as
being able to write (in Io):
elements sortBy( position )
elements map( * 2 )
elements select( size > 5 )


This same ability in Io allowed me to add a debugging method "p" (in
homage of Ruby) that labels a value with the exact call you made. For
example:

# In Io with my custom method (not Ruby)
p( gk )
#=> gk is Person_0x4de0d8:
#=> name = "Gavin Kistner"
#=> nick = "Phrogz""

p( gk name )
#=> gk name is Gavin Kistner

p( gk nick size )
#=> gk nick size is 6



[1] http://www.iolanguage.com/
 
Reply With Quote
 
Clifford Heath
Guest
Posts: n/a
 
      02-07-2008
Phrogz wrote:
> I've been learning Io[1] recently. Io (like Lisp, I gather) allows
> lazy evaluation of method arguments.

....
> In Io, the "isCool?" method/message isn't (necessarily) evaluated when
> you call the select method.


This is known as "call by name", as opposed to by reference or by value.
It was, more than anything, the single thing that caused the most difficulty
for the authors of Algol68 optimising compilers .

Niklaus Wirt once joked that Europeans (who know how to pronounce his name)
called him by name, whereas Americans called him by value (nickel's worth).
Maybe apocryphal, but funny .

Clifford Heath.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Like all great travelers, I have seen more than I remember andremember more than I have seen. shenrilaa@gmail.com Java 0 03-06-2008 08:11 AM
Like all great travelers, I have seen more than I remember andremember more than I have seen. shenrilaa@gmail.com C++ 0 03-05-2008 08:41 AM
Like all great travelers, I have seen more than I remember andremember more than I have seen. shenrilaa@gmail.com C Programming 0 03-05-2008 03:26 AM
had not seen this before Computer Support 8 07-28-2004 01:19 AM
Computer problems not seen before David Computer Support 7 06-26-2004 01:43 AM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57