From: "David A. Black" Date: 2009-07-15T05:23:47+09:00 Subject: Re: Twelve rules of Ruby Hi -- On Wed, 15 Jul 2009, Joel VanderWerf wrote: > David A. Black wrote: >> Hi -- >> >> On Wed, 15 Jul 2009, Joel VanderWerf wrote: >>> As you [Rick] say, the location of such intelligence is a question that >>> can >>> wait until someone starts poking around in the interpreter. >> >> Yes and no. I'm all for poking into interpreters (if you don't believe >> me, see http://ruby-versions.net :-) but I absolutely don't believe >> that one has to hitch descriptions of Ruby's object model to >> descriptions of specific interpreters. > > Exactly. There might be a compatible ruby interpreter in which each object > really does "have", in every possible sense of the word, all of the methods > that obj.send(:methods) lists. The difference between this and MRI with its > own lookup algorithm is unlikely to matter to a beginner, as long as s/he has > a consistent way of talking about the methods that an object responds to, and > how they got that way. The things I'm talking about are not MRI quirks, though; they're ways of modeling why things happen the way they do in (what I still insist on thinking of as :-) Ruby itself. I definitely do not believe it's a good idea to embargo all observations about the Ruby object model, beyond "objects have methods", on the grounds that they're just artifacts of MRI. super is a good example. A lot of people who've used Ruby for a while have a general -- or, I should say, specific -- idea that super calls "the same method, in the superclass". Consider this code: module M def talk; puts "In M"; end end class A include M def talk; puts "In A"; super; end end a = A.new a.talk # => In M\nIn A Two observations. First, any interpreter that did not produce the above results -- and for which an account involving method lookup along a class/module path therefore did not make sense -- I would not describe as a Ruby interpreter. Obviously, if Matz removes classes from Ruby (or whatever), things will change. But as of today, and the foreseeable future, Ruby produces that result. Second, I see no reason to tie my hands, in trying to account for the behavior of super (and a whole bunch of other things), by ruling out of court an account of the method lookup heuristics of the Ruby object trying to resolve a message. I don't mind if it's slightly anthropomorphic, or if parts of it are optimized away by such-and-such an interpreter. The high-percentage thing, at least for someone learning Ruby, is to gain the ability both to understand as much code as possible and to bring as many productive techniques as possible to bear on writing code. >>> For a beginner, it's more important to have a _model_ of how method lookup >>> works (model in the sense of science, not rails). If the easiest way of >>> stating this model is in terms of what methods an object has (and what >>> class they were acquired from), so be it. >> >> It's the easiest at the very beginning, but it quite quickly (say, >> early in the afternoon on the first day of training :-) becomes more >> of a hindrance than a help. Then, once someone understands what else >> is going on -- that is, once someone graduates to a more featureful >> model, one that encompasses more of Ruby's observable behavior -- >> "has" reverts to being helpful, because it's the most sensible >> informal way of stating the relation between an object and a method. >> (Or "concise", if you don't like "informal".) > > I'd explain these concepts in terms of the basic tools that I, even after > years of rubying, still use to explore the capabilities of an object: > > irb(main):001:0> s = "foo" > irb(main):003:0> s.methods.grep /slice/ > irb(main):005:0> s.class.ancestors > irb(main):006:0> String.instance_methods(false) > irb(main):007:0> s.method :dup # to find out where the method came from > => # Yes, that would be chapter 15 :-) The thing is, I'm a great non-believer in the "winner take all", zero-sum approach to these things. Prompting people to rethink the notion of an object "having" methods, so that they start to see the message-resolution heuristics more clearly, in no way entails *not* using the techniques you've listed here for explanatory purposes. I don't feel I have to choose. > I still think of objects as having methods, because Object#methods tells me > what methods an object has. (Or which ones it will be able to find on its lookup path :-) > That's not incompatible with talking about how an object came to have those > methods, and all the different ways that can happen. Right -- thus one circles back to it. Believe me, I'm not the "has" police :-) I say "has an x method" all over the place. I just find that teaching people that there's more going on -- and, specifically, positioning that "more" as residing under the hood of the "has" -- is very productive. David -- David A. Black / Ruby Power and Light, LLC Ruby/Rails consulting & training: http://www.rubypal.com Now available: The Well-Grounded Rubyist (http://manning.com/black2) Training! Intro to Ruby, with Black & Kastner, September 14-17 (More info: http://rubyurl.com/vmzN)