From: Eric Christopherson Date: 2010-10-15T07:28:16+09:00 Subject: Re: Why does a lot of code not include parenthesis? On Thu, Oct 14, 2010 at 10:22 AM, Chad Perrin wrote: > On Thu, Oct 14, 2010 at 09:51:19AM +0900, Eric Christopherson wrote: >> >> I'm not sure I follow. It sounds like you're saying that the >> expression "o.foo" can mean either "invoke method foo on object o" or >> "instance variable foo of object o", depending on how o is defined. >> But AIUI "o.foo" can only ever mean the former. (That method might be >> an accessor for an instance variable, but you still can't refer to an >> instance variable directly using dot notation.) > > This is true but, to be fair, it can look an awful lot like direct access > to the variable: > >    > class Foo >    >   def initialize(foo=nil) >    >     @foo = foo >    >   end >    >   attr_accessor :foo >    > end >    => nil >    > o = Foo.new >    => # >    > o.foo = 'foo' >    => "foo" >    > puts o.foo >    foo >    => nil Right, but I don't see what it has to do with the optionality of parentheses. The point made earlier (one I'd seen before) was that the optionality of parentheses made refactoring easy. David said: > So here, the only real question is whether it's more common to want to deal > with methods directly this way, or to want to refactor instance variables into > methods. I like that Ruby's approach has everything entirely encapsulated by > default -- attr_accessor means I always have the option to replace an instance > variable with a pair of methods. Sure, within a class you can replace the instance variable @foo with the accessor methods foo and foo= (with or without parentheses), or vice versa; but you still need to add or remove the @ sign when you change between instance variable and method. The only context I can think of where a given token can refer to either a method call or a variable is within a method or other block that allows local variables. E.g.: > def foo > # ... > puts x > # ... > end Here, if you don't look at the whole method, you can't tell if "x" refers to a local variable x, or a method call equivalent to self.x. However, if you look at the whole method, you can see whether x is ever assigned to; if it is assigned to without using "self.", you know it's a local variable.