I came across this :
elements.sort_by(&:position).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
I came across this :
elements.sort_by(&:position).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
On Feb 6, 2008, at 10:55 PM, Rob S. wrote:
I came across this :
elements.sort_by(&:position).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(:position) }.each
The “something” is a Rails project, isn’t it?
== vendor/rails/activesupport/lib/active_support/core_ext/symbol.rb ==
class Symbol
for enumerations. Examples:
p.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
On 2/6/08, Rob S. [email protected] wrote:
I came across this :
elements.sort_by(&:position).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. &:position == :position.to_proc == proc { |element, *args|
element.position(*args) }
So elements.sort_by(&:position) is shorthand for sorting the elements
by position.
jeremy
Jeremy K. wrote:
Sure. &:position == :position.to_proc == proc { |element, *args|
element.position(*args) }So elements.sort_by(&:position) 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.
On Feb 7, 2008 4:14 AM, Rob S. [email protected] 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
On Thu, Feb 7, 2008 at 6:04 AM, Martin DeMello [email protected]
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/fun-with-symboltoproc.html
On Feb 6, 2008, at 20:04 , Rob B. wrote:
You’ve found Symbol#to_proc
That line is equivalent to:
elements.sort_by {|e| e.send(:position) }.each
Buyer beware:
#!/usr/local/bin/ruby -w
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
On Feb 6, 8:55 pm, Rob S. [email protected] wrote:
I came across this :
elements.sort_by(&:position).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:
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:
p( gk )
#=> gk is Person_0x4de0d8:
#=> name = “Gavin K.”
#=> nick = “Phrogz”"
p( gk name )
#=> gk name is Gavin K.
p( gk nick size )
#=> gk nick size is 6
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 H…
On Feb 7, 2008 1:16 PM, Ryan D. [email protected] wrote:
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.001288)
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
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
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
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
Io (like Lisp, I gather) allows lazy evaluation of method arguments.
Are you referring to Lisp’s macro facility? AFAIK macros are usually
expanded at load/compile time. Since everything is a s-expression in
lisp, the macro gets its arguments as list and can process them. The
macro call is then replaced with the result. Or something along this
line.
It seems Io provides a similar facility to treat code as data, which
is cool. Unfortunately I’m not able to compile it. IIRC Forth was able
to do something similar too BTW (just a side-note).
Since ruby doesn’t have this feature (unless you use parsetree and
ruby2ruby maybe), the ruby equivalent are strings, I’d say. One could
thus write something like:
class Array
def select_by(snippet)
rv = []
self.each do |e|
rv << e if e.instance_eval '%s %s' % [e.inspect,
snippet]
end
rv
end
end
a = [1,2,3,4,5]
a.select_by '> 3'
Which is about the same as your io example. It would be nice of course
to be able to have real macros that are expanded at load time so that
one could write something like the following which is incorrect ruby
syntax and would have to be rewritten before the parser tries to make
sense out of it:
module Macros
def select_by(code)
%{select {|e| e #{code}}}
end
end
a = [1,2,3,4,5]
a.select_by(> 3)
This would require that macro names are unique though. But it’s just a
delirious day-dreaming anyway.
Regards,
Thomas.
Hello Rob
We can send arguments, Following is the way, But it throws an error.
def to_proc
Proc.new { |*args| args.shift.send(self, *args) }
end
arr.collect(&[:concat,“Rocking”])
__send__': [:concat, "dee"] is not a symbol (TypeError) from sample.rb:41:into_proc’But if we change the implementation of to_proc then it works.
def to_proc
lambda {|target| target.send *self}
end
arr.collect(&[:concat,“Rocking”])
o/p => [“rubyRocking”, “railsRocking”, “rjaxRocking”]
I don’t know how.
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.
Sponsor our Newsletter | Privacy Policy | Terms of Service | Remote Ruby Jobs