Variable/Method ambiguity

Pickaxe p.212 explains the subject well enough, however here’s an interesting case:

class Test
def name=(name)
puts "Called ‘name=’ …"
end
def test
name = "aaa"
end
end

Test.new.test

I would expect to see “Called ‘name=’ …”, as Ruby can realize here that method “name=” is available and call it. However, nothing is printed, meaning that an assignment to local variable “name” took place.

Is it only me who thinks that such behaviour is inconsistent?

Actually, I am trying to use Ruby as some description language. I eval file

···

product {
name = "Some name"
description = “Some description”

}

in the binding of the class:

class Registry
def product
@product = Product.new
yield if block_given?

end
def name=(name)
@product.setName(name)
end
def description=(description)
@product.setDescription(description)
end
def process(file)
contents = File.readlines(file).join
eval contents, binding, file
end
end

Alas, it does not work as I would expect :frowning:

Thanks in advance for any input,
Gennady.

Use self.name = “aaa” to call the method. I’ll leave it to others to
comment on perceived inconsistency.

Cheers,
Gavin

···

On Tuesday, May 6, 2003, 10:49:44 AM, Gennady wrote:

Pickaxe p.212 explains the subject well enough, however here’s an interesting case:

class Test
def name=(name)
puts “Called ‘name=’ …”
end
def test
name = “aaa”
end
end

Test.new.test

I would expect to see “Called ‘name=’ …”, as Ruby can realize here
that method “name=” is available and call it. However, nothing is
printed, meaning that an assignment to local variable “name” took
place.

Hi –

Pickaxe p.212 explains the subject well enough, however here’s an interesting case:

class Test
def name=(name)
puts “Called ‘name=’ …”
end
def test
name = “aaa”
end
end

Test.new.test

I would expect to see “Called ‘name=’ …”, as Ruby can realize here
that method “name=” is available and call it. However, nothing is
printed, meaning that an assignment to local variable “name” took
place.

Is it only me who thinks that such behaviour is inconsistent?

I don’t think it’s inconsistent. I think it would be inconsistent,
and confusing, if this:

class A
def thing=(x); end
def other; thing = 100; end
end

were different from this:

class A
def other; thing = 100; end
def thing=(x); end
end

or from this:

class A
def blah=(x); end
def other; thing = 100; end
end

As I understand it, the consistency is that, in all cases, the
receiver of a method must appear explicitly, unless both of these
things are true:
(a) the receiver is self;
(b) the variable could not be an already-defined local variable,
or a local variable in the process of being defined.

I think this is the only algorithm that won’t cause shifting behavior
in cases like the ones above.

David

···

On Tue, 6 May 2003, Gennady wrote:


David Alan Black
home: dblack@superlink.net
work: blackdav@shu.edu
Web: http://pirate.shu.edu/~blackdav

> Actually, I am trying to use Ruby as some description language. I eval = > file

use yaml - love yaml

i was doing something similar a while back. yaml is better :wink:

-a

···

On Tue, 6 May 2003, Gennady wrote:

Ara Howard
NOAA Forecast Systems Laboratory
Information and Technology Services
Data Systems Group
R/FST 325 Broadway
Boulder, CO 80305-3328
Email: ara.t.howard@fsl.noaa.gov
Phone: 303-497-7238
Fax: 303-497-7259
====================================

I don’t. I think you want Ruby to be ‘clever’ in examining the object to
work out whether a method exists. However the decision “is foo a local
variable or a method” is currently made at compile time, based on whether an
assignment to ‘foo’ has been seen previously in the method:

def foo
1
end
def test
3. times do
p foo #>> 1 (the method)
foo = 2
p foo #>> 2 (the variable)
end
end
test

prints 1 2 1 2 1 2.

If this were to be made dynamic, then Ruby could not even code efficiently
“foo = foo + 1”, because it wouldn’t be known until runtime whether ‘foo’
and ‘foo=’ were methods or local variables.

Perhaps more importantly, the behaviour of the code could also change
catastrophically if someone accidentally introduced a method into an object
which happened to have the same name as a local variable within one of its
methods. i.e. at the moment local variables are to a degree ‘protected’ from
this sort of outside interference.

It’s all down to Ruby’s decision to try and make things just work without
declarations. You could always introduce declarations for local variables,
or disambiguate them with a prefix:

 $foo = $foo + 1

but then Ruby would start turning into Perl…

Cheers,

Brian.

···

On Tue, May 06, 2003 at 09:49:44AM +0900, Gennady wrote:

class Test
def name=(name)
puts “Called ‘name=’ …”
end
def test
name = “aaa”
end
end

Test.new.test

I would expect to see “Called ‘name=’ …”, as Ruby can realize here that method “name=” is available and call it. However, nothing is printed, meaning that an assignment to local variable “name” took place.

Is it only me who thinks that such behaviour is inconsistent?

In my never ending quest for knowledge, I decided to learn scheme,
which is wonderful. There is a programming environment for scheme
called Dr. Scheme that is really good. Dr. Scheme is very user friendly
and very good for educational purposes. It is available for Windows
95+, Unix and Mac OS X (my platform). Among other things, it has one
window for function definitions and one for interactions. The contents
of the two windows are kept in synch.

I would really like it if someone would create something like this for
Ruby.

The web site is at

http://www.drscheme.org/

I don’t think it’s inconsistent. I think it would be inconsistent,
and confusing, if this:

class A
def thing=(x); end
def other; thing = 100; end
end

were different from this:

class A
def other; thing = 100; end
def thing=(x); end
end

These 2 cases would work the same, as actual execution happens after
all methods are defined – so it would call thing=() in both.

or from this:

class A
def blah=(x); end
def other; thing = 100; end
end

As I understand it, the consistency is that, in all cases, the
receiver of a method must appear explicitly, unless both of these
things are true:
(a) the receiver is self;
(b) the variable could not be an already-defined local variable,
or a local variable in the process of being defined.

I think this is the only algorithm that won’t cause shifting behavior
in cases like the ones above.

I know that I can use self.name= as Gavin suggested (it does not look
pretty for my task, though) and I understand all consequences presented
by David, and yet … it was so tempting to want to be able to use it
my way. Nevermind, I use slightly different approach now that works :wink:

Gennady.

···

On Monday, May 5, 2003, at 06:31 PM, dblack@superlink.net wrote:

> Actually, I am trying to use Ruby as some description language. I > eval = > file

use yaml - love yaml

i was doing something similar a while back. yaml is better :wink:

I will consider using YAML any time soon, however in my case
descriptional form, like “name=”, should be used together with
instructional, like “install into” or “generate as”. And I am not sure
YAML can handle this. But I will definitely give it a shot.

Gennady.

···

On Monday, May 5, 2003, at 07:43 PM, ahoward wrote:

On Tue, 6 May 2003, Gennady wrote:

-a

Ara Howard
NOAA Forecast Systems Laboratory
Information and Technology Services
Data Systems Group
R/FST 325 Broadway
Boulder, CO 80305-3328
Email: ara.t.howard@fsl.noaa.gov
Phone: 303-497-7238
Fax: 303-497-7259
====================================