a Python person's experience with Ruby

MonkeeSage MonkeeSage at gmail.com
Sun Dec 9 19:23:24 EST 2007


Hi Bruno,

I think that we've been having a mainly "semantic" (pun intended)
dispute. I think you're right, that we've been using the same words
with different meanings.

I would like to say firstly that I've been using python for a few
years now (about three I think), and I think I have a basic grasp of
the object system and so forth (e.g., I understood your example with
the apply decorator and properties). I read the docs when I first
started learning python (along with Fredrik Lundh's page about python
objects and more recently "call by object"). But I also own up to my
ignorance. I'm not a guru by any means. So you'll have to forgive me
if my ignorance has gotten in the way. I'll definitely re-read the
docs tonight.

I would like to (try to) clarify a little about my use of wording. By
"attribute" I was referring to a member of an object (*other than*
toplevel). I was of course using "method" to refer to callable
attributes (and I would use "function" for callable attributes bound
to toplevel), and I was using "variable" to refer to non-callable
attributes. By "tagging" I meant that attributes without a
"tag" (e.g., __call__) are not included in the MRO for an object; they
must be "tagged" as something other than a "variable".

As for ruby, I think the opcodes will help me clarify...

>> require 'parse_tree'
=> true
>> ParseTree.translate(%q{
class A
  def foo
    "bar"
  end
end
A.new.foo
})
=> [:block, [:class, :A, nil, [:scope, [:defn, :foo, [:scope, [:block,
[:args], [:str, "bar"]]]]]], [:call, [:call,
[:const, :A], :new], :foo]]

Notice that #new and #foo are both CALL ops. All attribute access is
CALL (i.e., "method"). There really is no such thing as a non-callable
"attribute" in ruby. Within the scope of a class (block, &c), there
can be non-callable members of course (LVAL), but "foo" can mean
either LVAL *or* FCALL, because there is no "tagging", it's just
whatever is in context and/or parsed first as a given type of object
(well there are a few other rules, but that's the main idea), with
"()" is a hint to help the parser when the expression is ambiguous:

a = 1
def a; 2; end
a   # [:lval :a] == a = 1
a() # [:fcall :a] == def ...

Given this, I see the addition the instance variable also being an
attribute as a *huge* difference between the ruby code and your
initial example. An attribute can be named the same as an lval and
return or set the value of the lval (e.g., @a), but it's no different
from any other method.

class A
  def initialize; @a = "blah"; end
  attr_reader :a
  def cheese; @a; end # exactly equivalent
end

But at the same time, I can see how my python example can be seen as
*wildly* different (WTF?) as well. Maybe there is no easy way to
provide a true formally equivalent translation due to the
implementation differences of the languages (or if Saphir-Whorf is
right, maybe we just can't think of it! ;)

Anyhow, sorry for the confusion.

Regards,
Jordan



More information about the Python-list mailing list