Kenneth McDonald
2009-Feb-06 00:07 UTC
How does something like ...sort_by(&:f) actually manage to function?
I''ve seen a claim on the web that &:f is just Ruby shorthand for &proc { |i| i.f }, but I''ve certainly never been able to get this &:f notation to work in standard ruby. Thanks, Ken --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
balint.erdi-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org
2009-Feb-06 00:13 UTC
Re: How does something like ...sort_by(&:f) actually manage to function?
It is not possible in "plain" ruby because Rails extends the Symbol class with the possibility of converting it into a Proc (that''s what happens when you precede something with a &). From the Rails source code: unless :to_proc.respond_to?(:to_proc) 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 end And it does come very handy indeed. Balint On Feb 6, 1:07 am, Kenneth McDonald <kenneth.m.mcdon...-rphTv4pjVZMJGwgDXS7ZQA@public.gmane.org> wrote:> I''ve seen a claim on the web that &:f is just Ruby shorthand for &proc > { |i| i.f }, but I''ve certainly never been able to get this &:f > notation to work in standard ruby. > > Thanks, > Ken--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Frederick Cheung
2009-Feb-06 01:24 UTC
Re: How does something like ...sort_by(&:f) actually manage to function?
On 6 Feb 2009, at 00:13, balint.erdi-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org wrote:> > It is not possible in "plain" ruby because Rails extends the Symbol > class with the possibility of converting it into a Proc (that''s what > happens when you precede something with a &). From the Rails source > code:Although it''s worth noting that Symbol#to_proc is in newer versions of ruby (1.9 and 1.8.7 IIRC) Fred> > > unless :to_proc.respond_to?(:to_proc) > 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 > end > > And it does come very handy indeed. > Balint > > On Feb 6, 1:07 am, Kenneth McDonald <kenneth.m.mcdon...-rphTv4pjVZMJGwgDXS7ZQA@public.gmane.org> > wrote: >> I''ve seen a claim on the web that &:f is just Ruby shorthand for >> &proc >> { |i| i.f }, but I''ve certainly never been able to get this &:f >> notation to work in standard ruby. >> >> Thanks, >> Ken > >--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Kenneth McDonald
2009-Feb-06 15:39 UTC
Re: How does something like ...sort_by(&:f) actually manage to function?
Thank you! Ken On Feb 5, 2009, at 6:13 PM, balint.erdi-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org wrote:> > It is not possible in "plain" ruby because Rails extends the Symbol > class with the possibility of converting it into a Proc (that''s what > happens when you precede something with a &). From the Rails source > code: > > unless :to_proc.respond_to?(:to_proc) > 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 > end > > And it does come very handy indeed. > Balint > > On Feb 6, 1:07 am, Kenneth McDonald <kenneth.m.mcdon...-rphTv4pjVZMJGwgDXS7ZQA@public.gmane.org> > wrote: >> I''ve seen a claim on the web that &:f is just Ruby shorthand for >> &proc >> { |i| i.f }, but I''ve certainly never been able to get this &:f >> notation to work in standard ruby. >> >> Thanks, >> Ken > >--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Kenneth McDonald
2009-Feb-06 15:58 UTC
Re: How does something like ...sort_by(&:f) actually manage to function?
OK, I see how this works now, but I can''t figure out how to get extra args in there, i.e. something like [1, 2, 3].collect(&:modulo, 2) doesn''t work because it''s improper Ruby syntax. I assume there''s a reason extra args are allowed, so could someone give a brief illustration of the calling convention? Thanks in advance, Ken On Feb 5, 2009, at 6:13 PM, balint.erdi-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org wrote:> > It is not possible in "plain" ruby because Rails extends the Symbol > class with the possibility of converting it into a Proc (that''s what > happens when you precede something with a &). From the Rails source > code: > > unless :to_proc.respond_to?(:to_proc) > 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 > end > > And it does come very handy indeed. > Balint > > On Feb 6, 1:07 am, Kenneth McDonald <kenneth.m.mcdon...-rphTv4pjVZMJGwgDXS7ZQA@public.gmane.org> > wrote: >> I''ve seen a claim on the web that &:f is just Ruby shorthand for >> &proc >> { |i| i.f }, but I''ve certainly never been able to get this &:f >> notation to work in standard ruby. >> >> Thanks, >> Ken > >--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Frederick Cheung
2009-Feb-06 16:28 UTC
Re: How does something like ...sort_by(&:f) actually manage to function?
On 6 Feb 2009, at 15:58, Kenneth McDonald wrote:> > OK, I see how this works now, but I can''t figure out how to get extra > args in > there, i.e. something like [1, 2, 3].collect(&:modulo, 2) doesn''t work > because > it''s improper Ruby syntax. I assume there''s a reason extra args are > allowed, > so could someone give a brief illustration of the calling convention? >I don''t think you can - you just have to use the longhand syntax in those cases. Fred> Thanks in advance, > Ken > > > On Feb 5, 2009, at 6:13 PM, balint.erdi-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org wrote: > >> >> It is not possible in "plain" ruby because Rails extends the Symbol >> class with the possibility of converting it into a Proc (that''s what >> happens when you precede something with a &). From the Rails source >> code: >> >> unless :to_proc.respond_to?(:to_proc) >> 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 >> end >> >> And it does come very handy indeed. >> Balint >> >> On Feb 6, 1:07 am, Kenneth McDonald >> <kenneth.m.mcdon...-rphTv4pjVZMJGwgDXS7ZQA@public.gmane.org> >> wrote: >>> I''ve seen a claim on the web that &:f is just Ruby shorthand for >>> &proc >>> { |i| i.f }, but I''ve certainly never been able to get this &:f >>> notation to work in standard ruby. >>> >>> Thanks, >>> Ken >>> > > > >--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
balint.erdi-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org
2009-Feb-06 17:38 UTC
Re: How does something like ...sort_by(&:f) actually manage to function?
The first of the parameters passed to the block is the object that is sent the message designated by the symbol. (Or in other words, the method designated by the symbol is called on the object that is the first parameter). So people.collect(&:name) works because the collect iterator yields a member of the people enumerable at each pass. Plus that object needs to have name method. The important part to understand is that any extra parameters the iterator yields to the block will be passed to the method. In the above case, there is none, because collect only yields one member, nothing more. I''ll give you an (very-convoluted) example because it is hard to understand without one: RND_TOP = 10 class Array def select_with_random selected = [] self.each do |e| selected << e if yield e, rand(RND_TOP) end selected end end numbers = Array.new(5) { rand(RND_TOP) } above = numbers.select_with_random(&:>) puts "numbers that are above another random number: #{above.inspect}}" So I added a select iterator to the Fixnum class which not only yields an element but also a random number. That random number is the extra parameter that will be passed to the method designated by the symbol, in this case, >. So iterating through random numbers, it will select those that are bigger than another random number (no sense at all, I know). The > method needs one parameter and it gets it. I am sure that this can have actual, real world uses, too, I just could not find out something realistic right now. Balint On Feb 6, 5:28 pm, Frederick Cheung <frederick.che...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> On 6 Feb 2009, at 15:58, Kenneth McDonald wrote: > > > > > OK, I see how this works now, but I can''t figure out how to get extra > > args in > > there, i.e. something like [1, 2, 3].collect(&:modulo, 2) doesn''t work > > because > > it''s improper Ruby syntax. I assume there''s a reason extra args are > > allowed, > > so could someone give a brief illustration of the calling convention? > > I don''t think you can - you just have to use the longhand syntax in > those cases. > > Fred > > > Thanks in advance, > > Ken > > > On Feb 5, 2009, at 6:13 PM, balint.e...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org wrote: > > >> It is not possible in "plain" ruby because Rails extends the Symbol > >> class with the possibility of converting it into a Proc (that''s what > >> happens when you precede something with a &). From the Rails source > >> code: > > >> unless :to_proc.respond_to?(:to_proc) > >> 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 > >> end > > >> And it does come very handy indeed. > >> Balint > > >> On Feb 6, 1:07 am, Kenneth McDonald > >> <kenneth.m.mcdon...-rphTv4pjVZMJGwgDXS7ZQA@public.gmane.org> > >> wrote: > >>> I''ve seen a claim on the web that &:f is just Ruby shorthand for > >>> &proc > >>> { |i| i.f }, but I''ve certainly never been able to get this &:f > >>> notation to work in standard ruby. > > >>> Thanks, > >>> Ken--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---