I''ve got two Models. A and B. Model A has an attribute "name". Model B has an attribute "title". I can get the name by a.method(:name).call I can NOT get the title by b.method(:title).call. Send works in both cases (a.send(:name), b.send(:title). I have rewritten my methods using send. But WHY did the former not work? -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
Bartek Puzoń wrote:> I''ve got two Models. A and B. Model A has an attribute "name". Model B > has an attribute "title". > > I can get the name by a.method(:name).call > I can NOT get the title by b.method(:title).call. > Send works in both cases (a.send(:name), b.send(:title). > > > I have rewritten my methods using send. But WHY did the former not work?In model A you have something like: def name ... end and in model B you don''t have the equivalent for title. Rails uses method_missing to dynamically create column methods for you without you needing to explicitly create them in your model unless you want to override the default behavior or add new ones. send will follow the path through method_missing, if it''s been defined, in search of the method to execute while method.call does not. I''m not a Ruby expert so I don''t know why there''s that difference. This is analogous to how respond_to? will return true for methods that are defined through method_missing but you don''t see them if you look at the methods array for that class. -- Michael Wang --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
dblack-TKXtfPMJ4Ozk1uMJSBkQmQ@public.gmane.org
2007-Aug-04 01:01 UTC
Re: method(std).call and send(sth)
Hi -- On Fri, 3 Aug 2007, Michael Wang wrote:> > Bartek Puzo wrote: >> I''ve got two Models. A and B. Model A has an attribute "name". Model B >> has an attribute "title". >> >> I can get the name by a.method(:name).call >> I can NOT get the title by b.method(:title).call. >> Send works in both cases (a.send(:name), b.send(:title). >> >> >> I have rewritten my methods using send. But WHY did the former not work? > > In model A you have something like: > > def name > ... > end > > and in model B you don''t have the equivalent for title. > > Rails uses method_missing to dynamically create column methods for you > without you needing to explicitly create them in your model unless you > want to override the default behavior or add new ones. > > send will follow the path through method_missing, if it''s been defined, > in search of the method to execute while method.call does not. I''m not a > Ruby expert so I don''t know why there''s that difference. > > This is analogous to how respond_to? will return true for methods that > are defined through method_missing but you don''t see them if you look at > the methods array for that class.Except... respond_to? doesn''t do that :-) It really can''t, since method_missing can do anything. You can sometimes (and people do) override respond_to? so that it reflects what your method_missing does, but it''s difficult if things are very dynamic. There was a thread about this on ruby-talk recently, with some interesting discussion of having a kind of third, high-level spec that could be used to define both method_missing and respond_to? to avoid having to do it all twice. I myself am not bothered by it; I think the implication of the "missing" in "method_missing" is that the object does *not* respond to the message, but a case can certainly be made that "respond" should include cases where the response is manufactured on the fly. David -- * Books: RAILS ROUTING (new! http://www.awprofessional.com/title/0321509242) RUBY FOR RAILS (http://www.manning.com/black) * Ruby/Rails training & consulting: Ruby Power and Light, LLC (http://www.rubypal.com) --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
dblack-TKXtfPMJ4Ozk1uMJSBkQmQ@public.gmane.org wrote:> Hi -- > > On Fri, 3 Aug 2007, Michael Wang wrote: > >> Bartek Puzoń wrote: >>> I''ve got two Models. A and B. Model A has an attribute "name". Model B >>> has an attribute "title". >>> >>> I can get the name by a.method(:name).call >>> I can NOT get the title by b.method(:title).call. >>> Send works in both cases (a.send(:name), b.send(:title). >>> >>> >>> I have rewritten my methods using send. But WHY did the former not work? >> In model A you have something like: >> >> def name >> ... >> end >> >> and in model B you don''t have the equivalent for title. >> >> Rails uses method_missing to dynamically create column methods for you >> without you needing to explicitly create them in your model unless you >> want to override the default behavior or add new ones. >> >> send will follow the path through method_missing, if it''s been defined, >> in search of the method to execute while method.call does not. I''m not a >> Ruby expert so I don''t know why there''s that difference. >> >> This is analogous to how respond_to? will return true for methods that >> are defined through method_missing but you don''t see them if you look at >> the methods array for that class. > > Except... respond_to? doesn''t do that :-) It really can''t, since > method_missing can do anything. You can sometimes (and people do) > override respond_to? so that it reflects what your method_missing > does, but it''s difficult if things are very dynamic.So is Rails doing something funky with respond_to? then to get that to work? E.g. if I have: class Author < ActiveRecord::Base def name end end class Post < ActiveRecord::Base # title is column in Post end And then in script/console I get this: >> a = Author.new => #<Author:0x349bee0 @new_record=true, @attributes={"name"=>nil}> >> a.method("name").call => nil >> a.methods.grep(/name/) => ["name", "table_name_prefix", "attribute_names", "table_name_suffix", "pluralize_table_names"] >> b = Post.new => #<Post:0x34891f0 @new_record=true, @attributes={"title"=>nil}> >> b.method("title").call NameError: undefined method `title'' for class `Post'' from (irb):5:in `method'' from (irb):5 >> b.methods.grep(/title/) => [] >> b.respond_to?("title") => true >> b.send("title") => nil -- Michael Wang --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
dblack-TKXtfPMJ4Ozk1uMJSBkQmQ@public.gmane.org
2007-Aug-04 02:20 UTC
Re: method(std).call and send(sth)
On Fri, 3 Aug 2007, Michael Wang wrote:> > dblack-TKXtfPMJ4Ozk1uMJSBkQmQ@public.gmane.org wrote: >> Hi -- >> >> On Fri, 3 Aug 2007, Michael Wang wrote: >> >>> Bartek Puzo wrote: >>>> I''ve got two Models. A and B. Model A has an attribute "name". Model B >>>> has an attribute "title". >>>> >>>> I can get the name by a.method(:name).call >>>> I can NOT get the title by b.method(:title).call. >>>> Send works in both cases (a.send(:name), b.send(:title). >>>> >>>> >>>> I have rewritten my methods using send. But WHY did the former not work? >>> In model A you have something like: >>> >>> def name >>> ... >>> end >>> >>> and in model B you don''t have the equivalent for title. >>> >>> Rails uses method_missing to dynamically create column methods for you >>> without you needing to explicitly create them in your model unless you >>> want to override the default behavior or add new ones. >>> >>> send will follow the path through method_missing, if it''s been defined, >>> in search of the method to execute while method.call does not. I''m not a >>> Ruby expert so I don''t know why there''s that difference.Just to comment on this point: the reason is that if you do this: obj.method("x").call by the time you get to the .call part, you''ve already failed if there''s no "x" method. So call will never be called.>>> This is analogous to how respond_to? will return true for methods that >>> are defined through method_missing but you don''t see them if you look at >>> the methods array for that class. >> >> Except... respond_to? doesn''t do that :-) It really can''t, since >> method_missing can do anything. You can sometimes (and people do) >> override respond_to? so that it reflects what your method_missing >> does, but it''s difficult if things are very dynamic. > > So is Rails doing something funky with respond_to? then to get that to work?Yes -- respond_to? is overriden in base.rb, and method_missing is engineered in parallel, so that column names will be treated as methods and will also return true for respond_to?. You can see a counter-example, where method_missing and respond_to? go in different directions, in the find_by_* family of AR class methods: >> User.find_by_nick("dblack") => #<User:0x335bbe8 @attributes={"modified_at"=>nil, ... >> User.respond_to?("find_by_nick") => false That''s basically what happens by default, while the behavior you''ve observed for the column names has to be brought about explicitly by overriding respond_to? David -- * Books: RAILS ROUTING (new! http://www.awprofessional.com/title/0321509242) RUBY FOR RAILS (http://www.manning.com/black) * Ruby/Rails training & consulting: Ruby Power and Light, LLC (http://www.rubypal.com) --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---