Why does a lot of code not include parenthesis?

J

Josh Cheek

[Note: parts of this message were removed to make it a legal post.]

-42.abs vs -42.abs()
In this case, the negative sign is also a method. Fully parenned, it looks
like 42.-@().abs() yikes!
 
D

David Masover

the only real argument for requiring parens is so that

o.foo # returns the method foo

as in javascript. other arguments are mostly religious.

I actually really like this about JavaScript, but as it turns out, JavaScript
has getters and setters. I'm guessing they've been added to the language
itself because they pretty much always existed as part of the browser's API --
think "location.href = foo" -- so it makes sense to expose them to developers.

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. True, I have setters and getters in
JavaScript, but they're the default in Ruby.
 
E

Eric Christopherson

I actually really like this about JavaScript, but as it turns out, JavaSc= ript
has getters and setters. I'm guessing they've been added to the language
itself because they pretty much always existed as part of the browser's A= PI --
think "location.href =3D foo" -- so it makes sense to expose them to deve= lopers.

So here, the only real question is whether it's more common to want to de= al
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 ins= tance
variable with a pair of methods. True, I have setters and getters in
JavaScript, but they're the default in Ruby.

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.)
 
S

Steve Howell

the only real argument for requiring parens is so that

  o.foo  # returns the method foo

as in javascript.  other arguments are mostly religious.

Python is like Javascript in that regard.

$ python200

$ irb
irb(main):001:0> def f(n=100) n * 2 end
=> nil
irb(main):002:0> f
=> 200
irb(main):003:0> f()
=> 200
irb(main):004:0> x = method:)f)
=> #<Method: Object#f>
irb(main):005:0> x.call(30)
=> 60

I work in both Python and Ruby, and I don't have a strong preference
for either style; it just requires a different mindset.
 
P

Phillip Gawlowski

=A0It takes a little judgment to
write readable code, regardless of the language, and in cases where
parentheses are optional, I find that obsessive adherence to "always use
parentheses" or "never use parentheses" rules are not conducive to
producing the most readable code.

In my opinion, parentheses should be used the way they are used in
maths: To make an ambiguous statement obvious.

For example: 2-x^2 can be interpreted in two ways: either (2-x) gets
squared, or only the x gets squared, and the product of this
subtracted from 2. Parentheses make the intention obvious: (2-x)^2.

It's a simple guide, but it has a lot of repercussions, especially
once you take into account precedence of operators (which can allow
you to remove or "force" you to add parens).

--=20
Phillip Gawlowski

Though the folk I have met,
(Ah, how soon!) they forget
When I've moved on to some other place,
There may be one or two,
When I've played and passed through,
Who'll remember my song or my face.
 
E

Eric Christopherson

This is true but, to be fair, it can look an awful lot like direct access
to the variable:

=A0 =A0> class Foo
=A0 =A0> =A0 def initialize(foo=3Dnil)
=A0 =A0> =A0 =A0 @foo =3D foo
=A0 =A0> =A0 end
=A0 =A0> =A0 attr_accessor :foo
=A0 =A0> end
=A0 =A0=3D> nil
=A0 =A0> o =3D Foo.new
=A0 =A0=3D> #<Foo:0x2854ec78 @foo=3Dnil>
=A0 =A0> o.foo =3D 'foo'
=A0 =A0=3D> "foo"
=A0 =A0> puts o.foo
=A0 =A0foo
=A0 =A0=3D> 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 de= al
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 ins= tance
variable with a pair of methods.

Sure, within a class you can replace the instance variable @foo with
the accessor methods foo and foo=3D (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.
 
D

David Masover

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.

My point was that JavaScript is like this, while Ruby is not. In JavaScript,
ordinarily, 'o.foo' can only ever mean an instance variable (it has to be
o.foo() to be a method, and if foo is a method, o.foo just gives you the
function object for that method). However, we can also specify a function
which will be called whenever someone tries to access 'o.foo'.

In other words, JavaScript makes it obnoxiously more tedious to either use
normal setters and getters (for example, o.foo, o.setFoo(), and o.getFoo()),
and even more tedious to define first-class setters and getters (so trying to
set or get o.foo actually calls your custom code instead). However, it makes
it very easy to remix objects, with far more flexibility and with a far more
primitive concept than mixins.

Ruby, by contrast, makes setters and getters easy (and required), which means
encapsulation is much easier -- but it makes certain kinds of code re-use
harder, and forces you to use classes and modules, whereas JavaScript starts
out with something simpler (prototypal inheritance), and allows you to pretty
much build any inheritance model you like on top of that.

Anyway, this is all about syntax. JavaScript makes it easier to do things one
way, Ruby makes it easier another way, but everything I mentioned should be
possible in both. It's just a question of how ugly it will be.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,143
Messages
2,570,822
Members
47,368
Latest member
michaelsmithh

Latest Threads

Top