# Method(std).call and send(sth)

**URL:** <https://www.ruby-forum.com/t/method-std-call-and-send-sth/111171>\
**Category:** Rails\
**Created:** [August 3, 2007, 2:46pm UTC](https://www.ruby-forum.com/t/method-std-call-and-send-sth/111171 "2007-08-03T14:46:18Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![bartek](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/bcef8e/32.png) [@bartek](https://www.ruby-forum.com/u/bartek)\
**Post date:** [August 3, 2007, 2:46pm UTC](https://www.ruby-forum.com/t/method-std-call-and-send-sth/111171/1 "2007-08-03T14:46:18Z")

</div>

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?

---

<div class="post-metadata">

**Author:** ![bartek](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/bcef8e/32.png) [@bartek](https://www.ruby-forum.com/u/bartek)\
**Post date:** [August 4, 2007, 2:52am UTC](https://www.ruby-forum.com/t/method-std-call-and-send-sth/111171/2 "2007-08-04T02:52:29Z")

</div>

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 W.

---

<div class="post-metadata">

**Author:** ![bartek](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/bcef8e/32.png) [@bartek](https://www.ruby-forum.com/u/bartek)\
**Post date:** [August 4, 2007, 3:01am UTC](https://www.ruby-forum.com/t/method-std-call-and-send-sth/111171/3 "2007-08-04T03:01:29Z")

</div>

Hi –

On Fri, 3 Aug 2007, Michael W. wrote:

> > I have rewritten my methods using send. But WHY did the former not work?  
> > 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](http://www.awprofessional.com/title/0321509242))  
RUBY FOR RAILS ([Ruby for Rails](http://www.manning.com/black))
- Ruby/Rails training  
& consulting: Ruby Power and Light, LLC ([http://www.rubypal.com](http://www.rubypal.com))

---

<div class="post-metadata">

**Author:** ![bartek](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/bcef8e/32.png) [@bartek](https://www.ruby-forum.com/u/bartek)\
**Post date:** [August 4, 2007, 4:20am UTC](https://www.ruby-forum.com/t/method-std-call-and-send-sth/111171/4 "2007-08-04T04:20:37Z")

</div>

On Fri, 3 Aug 2007, Michael W. wrote:

> > > > I can get the name by a.method(:name).call
> > > 
> > > 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](http://www.awprofessional.com/title/0321509242))  
RUBY FOR RAILS ([Ruby for Rails](http://www.manning.com/black))
- Ruby/Rails training  
& consulting: Ruby Power and Light, LLC ([http://www.rubypal.com](http://www.rubypal.com))

---

<div class="post-metadata">

**Author:** ![bartek](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/bcef8e/32.png) [@bartek](https://www.ruby-forum.com/u/bartek)\
**Post date:** [August 4, 2007, 3:32am UTC](https://www.ruby-forum.com/t/method-std-call-and-send-sth/111171/5 "2007-08-04T03:32:31Z")

</div>

removed\_email\_address@domain.invalid wrote:

> > > Send works in both cases (a.send(:name), b.send(:title).
> > 
> > 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 W.
