From: dblack@... Date: 2006-07-08T01:28:53+09:00 Subject: Re: About 1.9 #__method__ feature. Hi -- On Fri, 7 Jul 2006, ara.t.howard@noaa.gov wrote: > i think it's fair to say the closest one can come to 'functional' style in > ruby is to use recieveless messages, eg > > def foo() bar end > def bar() 42 end > > bar # pretend functional. really it's self.bar of course Yes and no. It has the effect as self.bar, but it actually *is* this: bar namely, a bare word, on the screen (or in a file, or whatever) with no explicit receiver. > it just so happens that this is also the requirement to call private methods > in ruby so a public interface to accomplish receiverless messages effectively > gets inside the object and becomes a private 'send'. > > i finally decided that i like funcall because i realized it's not __only__ an > > instance_eval{ send msg } > > but is simply a generic way of doing receiverless calls. there are other > possible uses for this technique and so a more generic name than > 'instance_send', etc. is appropriate. I disagree. I don't think there's such a thing as a "receiverless call", outside of what's actually visible to the eye. I don't see any advantage to stretching the term to mean something other than "a method call without an explicit receiver". It's not even clear what it would mean. > matz? > >> funcall itself isn't being called functionally > > indeed. it's calling 'meth' functionally. I'd say it's sending the method "meth" to an object symbolically. I don't don't see this as a functional-style call of "meth". A functional-style call of meth would look like this: meth >> , and meth isn't being called at all -- that is, you don't see this in the >> program: >> >> meth > > that's a bit weak. as programmers i think we can all agree that tons of > methods get 'called' even though we don't see them. that's the very idea > behind abstraction after all - you don't think people don't realize that > > belongs_to ... > > actually 'calls a bunch of stuff' do you? anyhow, i think that even a below > average ruby coder has no issue understanding that some methods call many > others behind the scenes. But that's the whole issue: how what's visible relates to what's behind the scenes. I like to keep the layers separate, not because we don't know that eventually "meth" gets called, but because understanding it sequentially makes more sense of more cases. This: obj.send(:meth) is, I think, best understood as "sending the message 'meth' symbolically to obj". If you call it "calling the method 'meth'", then you have to back-pedal to deal with things like method_missing, private methods, and so on. Yes, it's convenient to talk about "calling meth on obj" when you do: obj.meth But it's not entirely accurate, and once the layers are splayed out with symbolic references to method names, I think it becomes quite important not to collapse message-sending and method-calling. Again, I'd rather just have simple names for what's actually there, rather than decide up front that it has to be called something else and then decide what the best alternative name is. >> and therefore it's impossible, I think, to talk about the "style" of the >> "method invocation". > > but it's only one layer of abstraction deep? we could easily reason to > ourselves, while coding, that we needed a way to call private methods and > start using > > obj.instance_eval{ send msg } > > after we did this three or four times we could abstract it into > > funcall = lambda{|obj, msg, *a| obj.instance_eval{ send msg, *a }} > > and away we'd go > > funcall[ list, :push, 42 ] > > now it's two layers of code reading to say that the style of method > invocation > is receiverless and that's it's preciesly that feature, that of having a > receiver, that makes a method call 'object oriented'. note that's it's also > not a purely procedure call because > > send msg, *a > > has the notion of context as in > > let self = me in > send msg, *a;; > > and it's this context, combined with the lack of an explicit receiver that > gives a functional flavour. But I don't want to go through two layers when I use a term like "receiverless". I want it to mean "without an explicit receiver", not "equivalent to what *would* be without an explicit receiver if it were being used in a way that required a decision as to the inclusion or exclusion of a receiver...." I would say that when you do: obj.send(:meth) the "receiver/receiverless" status of the execution of the method "meth" is undefined. There's no opportunity for there to be or not be a receiver; it's not that kind of operation. David -- "To fully realize the potential of Rails, it's crucial that you take the time to fully understand Ruby--and with "Ruby for Rails" David has provided just what you need to help you achieve that goal." -- DAVID HEINEMEIER HANSSON, in the foreword to RUBY FOR RAILS. Complete foreword & sample chapters at http://www.manning.com/black!