Ambiguity between local variable assignment and writter method

now there only seems two options left, and they are both constructions.
the construction just stated above (:=) or, and i think the proper way
to have done it, a prefix symbol for local variables.

%localvariable = ‘i am me, not some method’

You’re kidding, right? I think one of the things that makes Perl so unreadable is the
amount of $$wildlife @growing %out[$of] =~ /the/ ${@writing} $! It’s nice the way ruby
doesn’t go over the top with it, and perhaps even at times uses it to improve readability.

no, if i were creating ruby now, i would very much consider doing that.
certainly it adds an extra char to all local vars, but it makes things
quite distinct.

unfortunately that’s just not going to go over well with the population
at large. and i can only wish that it was included early on. all
variables would have a prefix (%, @, @@, $) and methods would not, Ruby
might be a tad faster, and our conversation would never had to exist.
:wink:

I’d say locals don’t use prefixes (prefices?) since locals are (one of) the most common
identifiers used, and that sort of junk ought to be minimized.

do you consider @, @@, and $ junk?

you know other languages have commands to specify the access level of
variables. so you can’t tell the difference just by looking at them. you
code something like ‘global avar’ or ‘public avar’.

I’d personally rather lose the o.member = ‘something’ notation for method calling. As
David Alan Black mentioned:

Isn’t it good to have to know when you’re calling a method and when
you’re assigning to a local variable :slight_smile:

so you think writer methods are the problem? what would they be replaced
with?

Anyhow, I wouldn’t consider anything backward-incompatible likely to be worthy of
Rubydom.

nor would i, well, unless it was really really good.

···

On Sat, 2002-08-10 at 04:06, George Ogata wrote:


~transami

nope, not a SmallTalker, and i assume there’s no pun intended :wink: but
perhaps not coincidently, i did recently discover Squeak.

···

On Sat, 2002-08-10 at 17:44, Albert Wagner wrote:

Hi, Tom. I see a pattern to all of your expectations for Ruby. Are you a
Smalltalker?


~transami

i’d like to refocus on this aspect of the ambiguity thread. from what’s
been posted thus far on the topic, it would seem it is best to always
use the accessor methods when they exist. i hanker to bet many of us do
not do this. and i think this has to do with the fact that the
@variables are more convenient, due to the extra thoguht that must go
into determining when self must be used (albiet small), and the fact
that @ is shorter than self. other reasons?

so your idea for the . shortcut may be very helpful in encouraging
better programming along these lines. currently ruby allows for space to
exist between the reciever, the dot, and the message call, but i imagine
it would be short work to adjust, and very rare to cause any code
breakage.

yet, i start to wonder, if using getter and setter methods is really how
instance variables should be effected in OOP, and not forgetting kents
discussion of “minimizing” the use of @ and @@ via accessor methods,
persistent local variables make worthy of consideration. a persitent
local variable is simply a variable whose value is not lost from one
call to the method it resides in to the next. quick psuedo-example:

def x(n)
persist :x
x = x + n
end

puts x(10) # → 10
puts x(20) # → 30

···

On Fri, 2002-08-09 at 13:30, Dave Thomas wrote:

This is an interesting issue: should internal users go via the setter
method or access the instance variable directly. Clearly it depends on
the circumstances, but I often find myself writing accessors that do
things such as lazy evaluation, or which set dirty flags for
persistent objects, and where I really do need to go via the method
form. For those times, it’s nice to have a shortcut, but it isn’t
something I’d fight hard for… :slight_smile:


~transami

From: “Tom Sawyer” transami@transami.net

unfortunately, this is actually bad form. if a class instance variable
is set up to be accessed via accessor methods, they should be used at
all times. even internally. while, it is functionally equal for the
simplist case, writter methods may do other things as well, like
validate the argument.

I can’t agree with that.

Surely a class is allowed to reference its own
member data as it chooses. If it bypasses some
kind of needed extra work in the setter, that’s
simply a bug in the code.

And how do bugs like this ever get in the code? By people
not taking steps to try to avoid the possibility of their
ever occurring in the first place. :slight_smile:

I’m not trying to argue absolutes about good form /
bad form here though - but in my own code on this issue
I tend to find myself in line with Tom Sawyer, in that I
try hard to set things up to minimize the possibility I
can screw things up later. :slight_smile:

If anything has the right and the need to know
the class’s internals, it is the class itself
and the programmer creating it.

Sure, I’d agree about the ‘right’ . . . but still would want
to minimise the Need…

Regards,

Bill

···

From: “Hal E. Fulton” hal9000@hypermetrics.com

Tom Sawyer transami@transami.net writes:

why couldn’t ruby just check to see if there was such a setter method
first, prior to assuming it a local variable assignment? the only
consequence of this would be that you could not use local variable names
identical to your method names. something i tend to do anyway.

It would have to check on every single assignment, at all times, in
your code.

1000.times do |i|
a = 1
def a=(v)
puts v
end if i == 9987
end

Dave

Because of the wild ways in which Ruby can do inheritance
(<,<<,#include,#extend) and delegation (#method_missing), methods may pop
up in unplanned spots. Your feature causes a leakage of influence between
the local namespaces and the method namespaces, which is highly
undesirable semantically (“hairy”), in addition of really slowing things
down.

···

On Sat, 10 Aug 2002, Tom Sawyer wrote:

why couldn’t ruby just check to see if there was such a setter method
first, prior to assuming it a local variable assignment? the only
consequence of this would be that you could not use local variable names
identical to your method names. something i tend to do anyway.


Mathieu Bouchard http://artengine.ca/matju

Tom Sawyer wrote:

no, if i were creating ruby now, i would very much consider doing that.
certainly it adds an extra char to all local vars, but it makes things
quite distinct.

Isn’t this a step backwards to “feeding compilers” instead of solving
problems?

do you consider @, @@, and $ junk?

Dunno about George, but I consider $ junk and I am very vary of using
@@. Ironically we’re arguing about writer methods inside classes, which
also distances us from the @.

So, while not quite junk, they are ugly, nececarry implementation
details that need to be hidden as soon as possible :slight_smile:

so you think writer methods are the problem? what would they be replaced
with?

Nothing stopping you from making traditional setter and getters. Writers
are external interface syntax sugar, IMHO.

···


([ Kent Dahl ]/)_ ~ [ http://www.stud.ntnu.no/~kentda/ ]/~
))_student
/(( _d L b_/ NTNU - graduate engineering - 5. year )
( __õ|õ// ) )Industrial economics and technological management(
_
/ö____/ (_engineering.discipline=Computer::Technology)

Tom Sawyer wrote:

no, if i were creating ruby now, i would very much consider doing that.
certainly it adds an extra char to all local vars, but it makes things
quite distinct.

I think it makes things less distinct. @, @@, and $ appear quite scarcely
(compared to locals), and so they stand out. Giving locals a prefix letter
blends the whole lot into an unreadable mess.

do you consider @, @@, and $ junk?

If they were used on every identifier, yes. If used sparingly (as in
current ruby), though, I think it can sometimes (ok, quite often) help you
follow code. I guess “that sort of junk” wasn’t a fair expression to use.

you know other languages have commands to specify the access level of
variables. so you can’t tell the difference just by looking at them. you
code something like ‘global avar’ or ‘public avar’.

Well, ‘public’ doesn’t really come into it here, does it? Ruby uses
methods for that to mimic the way other languages do it.

I wasn’t suggesting that we rid them all (I said “minimize”, not
“eliminate”), just that they should be used only when really needed, and
when the alternatives aren’t better. Prefix symbols have a side-effect of
making things stand out, and when too much stands out, it just becomes
noise.

I’d personally rather lose the o.member = ‘something’ notation for method
calling. As David Alan Black mentioned:

Isn’t it good to have to know when you’re calling a method and when
you’re assigning to a local variable :slight_smile:

so you think writer methods are the problem? what would they be replaced
with?

set_x methods, as is used in most traditional OO languages. They should
still be magically generated using attr_*.

I understand the motive of member=(), though. Since the interface of a
class consists only of methods, o.member = ‘x’ has no meaning, so why not
make that a method too? The problem is when it’s used inside a class, when
you can omit the “o.”, and a gotcha arises from potential ambiguity. I
wonder if simply leaving “o.member = ‘x’” as illegal ruby would’ve been
better.

Just curious. I used Smalltalk exclusively for about 15 years. The syntax is
beautiful and elegant. But I grew weary of the huge image based model.

···

On Sunday 11 August 2002 02:07 pm, Tom Sawyer wrote:

On Sat, 2002-08-10 at 17:44, Albert Wagner wrote:

Hi, Tom. I see a pattern to all of your expectations for Ruby. Are you
a Smalltalker?

nope, not a SmallTalker, and i assume there’s no pun intended :wink: but
perhaps not coincidently, i did recently discover Squeak.

Hi –

i’d like to refocus on this aspect of the ambiguity thread. from what’s
been posted thus far on the topic, it would seem it is best to always
use the accessor methods when they exist. i hanker to bet many of us do
not do this. and i think this has to do with the fact that the
@variables are more convenient, due to the extra thoguht that must go
into determining when self must be used (albiet small), and the fact
that @ is shorter than self. other reasons?

I have to admit that neither of those things bothers me at all. Ruby
is concise enough that three characters one way or another, on
relatively rare occasions, doesn’t bother me. And, as I’ve said,
knowing when to specify the receiver should not be a burden; it just
means you know what your code is doing. (We’ve probably spent more
thought and typing on this thread than everyone on this list will
spend thinking about and typing ‘self.’ in their combined lifetimes
:slight_smile:

In any case – assigning to @var is only convenient if it does what
you want. I tend to lean toward using the accessor methods for
attributes, even inside a class, since those methods may be doing
things far beyond just setting or getting the instance variable
associated with their name. The raw @thing=x probably works, in
practice, quite often, but if the object has a #thing= method, there
might be a real necessity to channel assignments through that.

David

···

On Mon, 12 Aug 2002, Tom Sawyer wrote:


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

Tom Sawyer wrote:

This is an interesting issue: should internal users go via the setter
method or access the instance variable directly. Clearly it depends on
the circumstances, but I often find myself writing accessors that do
things such as lazy evaluation, or which set dirty flags for
persistent objects, and where I really do need to go via the method
form. For those times, it’s nice to have a shortcut, but it isn’t
something I’d fight hard for… :slight_smile:

i’d like to refocus on this aspect of the ambiguity thread. from what’s
been posted thus far on the topic, it would seem it is best to always
use the accessor methods when they exist. i hanker to bet many of us do
not do this. and i think this has to do with the fact that the

It has been asserted. I don’t think that it has been generally agreed.
Within a class accessor values may be either used or not used depending
on why they were created, and what the cost of using them is. Partially
also on how large the class is, whether the change is being made as a
part of the same declaration that was the original class declaration, etc.

Generally, if the class variable is set or read at a distance, either
logical or physical, from the original declaration, then accessors
should be used, and this can be sufficient reason to create them. Also
generally if there is excessive cost to using them, then they should be
avoided. Neither of these factors are all-or-nothing factors, e.g. if
they are private variables, there may be a disinclination to create
accessors even if they are accessed at a large distance from the
original declaration. And if they are sufficiently expensive to use,
there will also be a great disinclination to use them unless they are
really needed.

These arguments are independant of the stylistic costs, but an easily
used syntax encourages the use of a feature even when it is
inappropriate, and a difficult syntax discourages the use of a feature
even when it is appropriate. So the features that are expected to be
more used should have the shorter/easier forms. (See Zipf’s law.)

···

On Fri, 2002-08-09 at 13:30, Dave Thomas wrote:


– Charles Hixson
Gnu software that is free,
The best is yet to be.

oh! the strangness of ruby’s beauty! :slight_smile:

your talking about a speed issue, yes? how significant?

···

On Fri, 2002-08-09 at 14:14, Dave Thomas wrote:

It would have to check on every single assignment, at all times, in
your code.

1000.times do |i|
a = 1
def a=(v)
puts v
end if i == 9987
end


~transami

How about:

class Person
def initialize(name, age)
@name = name # calls name=(name) if self.name= exists
@age = age # set @age because not self.age=
end

def name=(name)
raise “Name needs to be String!” unless name.kind_of? String
@name = name # sets @name because in scope of name=
end
end

You change the behavior of @var=value to call the self.var= method if
it exists unless you are in the self.var= method, then you set the var.

It would only effect performance of @var= (or @var for reader)

-rich

From: Mathieu Bouchard [mailto:matju@sympatico.ca]
Sent: Friday, August 09, 2002 4:47 PM
To: ruby-talk ML
Subject: Re: ambiguity between local variable assignment and writter
method

why couldn’t ruby just check to see if there was such a setter
method
first, prior to assuming it a local variable assignment? the only
consequence of this would be that you could not use local variable
names
identical to your method names. something i tend to do anyway.

Because of the wild ways in which Ruby can do inheritance
(<,<<,#include,#extend) and delegation (#method_missing), methods may
pop
up in unplanned spots. Your feature causes a leakage of influence
between
the local namespaces and the method namespaces, which is highly
undesirable semantically (“hairy”), in addition of really slowing
things

···

-----Original Message-----
On Sat, 10 Aug 2002, Tom Sawyer wrote:
down.


Mathieu Bouchard http://artengine.ca/matju

leakage of influence? in all other cases the method is looked up. if i
have:

p = proc { joe }
p.call

what do i get?

undefined local variable or method ‘joe’

one or the other. there’s already “influence”.

i think speed is really the only possible draw back. but i don’t know
how much speed loss it would entail. additonally an explict local
assignment operator could still be an option:

localvar .= ‘whatever’

with this, or some equivalent notation, the lookup speed loss would be
circumvented.

~transami

···

On Fri, 2002-08-09 at 14:47, Mathieu Bouchard wrote:

On Sat, 10 Aug 2002, Tom Sawyer wrote:

why couldn’t ruby just check to see if there was such a setter method
first, prior to assuming it a local variable assignment? the only
consequence of this would be that you could not use local variable names
identical to your method names. something i tend to do anyway.

Because of the wild ways in which Ruby can do inheritance
(<,<<,#include,#extend) and delegation (#method_missing), methods may pop
up in unplanned spots. Your feature causes a leakage of influence between
the local namespaces and the method namespaces, which is highly
undesirable semantically (“hairy”), in addition of really slowing things
down.

i ran a little benchmark to see what kind of speed hit my solution would
incur. it looks to be quite small, but there dosen’t seem to be any way
to be sure b/c i don’t know how ruby works under the hood. but i gave it
shot to at least get an idea of the worst case. (results below)

require ‘benchmark’

include Benchmark

n = 100000

def a1
a = 1
end

def a2
a1
end

def a3
end

bm do |x|
GC.start
x.report(“a1”) { n.times { a1 } }
GC.start
x.report(“a2”) { n.times { a2 } }
GC.start
x.report(“a=1”) { n.times { a=1 } }
GC.start
x.report(“a=1; a”) { n.times { a=1; a } }
GC.start
x.report(“a3”) { n.times { a3 } }
GC.start
x.report(“a3; a=1”) { n.times { a3; a=1 } }
end
user system total real
a1 0.080000 0.000000 0.080000 ( 0.087665)
a2 0.120000 0.000000 0.120000 ( 0.123336)
a=1 0.070000 0.000000 0.070000 ( 0.063004)
a=1; a 0.080000 0.000000 0.080000 ( 0.083761)
a3 0.060000 0.000000 0.060000 ( 0.076508)
a3; a=1 0.080000 0.000000 0.080000 ( 0.111779)

notice that the first call looks up a1 and the executes it. the second
looks up a2, executes it, looksup a1, and executes it. so between the
two the time it takes to do a method lookup (out of all the possible
methods that might respond) will be approx 1/2 thier difference of
.035671, thus .0178355.

then the fourth report assigns a local variable, and the last assigns a
local varibale and then looks it up. so the time to look up a local
variable is their difference, .020757, and there’s only one local
variable in that scope!

so we can already see that the its faster to look up methods then it is
to lookup local variables (how does that happen?)

finally the time it takes to do a local assignment is the difference of
5 and 6, approx .035271. about twice as long as a lookup.

i’m not sure how ruby works under the hood, but given these results, i
am starting to wonder if looking up local variables and looking up
methods is done with the same lookup table. in which case, given that
ruby might have to check this table before assignment, there would be
practically NO performance loss. and if not, WORST CASE looks to be
about 30% on local assignments. ummm… thats about 4-5 months or
moore’s law.

···


~transami

Tom Sawyer wrote:
So, while not quite junk, they are ugly, nececarry implementation
details that need to be hidden as soon as possible :slight_smile:

how might you do that? as far i can tell that would involve declaring
variables. i don’t know how i feel about that.

Nothing stopping you from making traditional setter and getters. Writers
are external interface syntax sugar, IMHO.

this is true. but i like the #writter= methods. ugh, there seems to
grand solution to this.

···

On Sat, 2002-08-10 at 05:26, Kent Dahl wrote:

([ Kent Dahl ]/)_ ~ [ http://www.stud.ntnu.no/~kentda/ ]/~
))_student
/(( _d L b_/ NTNU - graduate engineering - 5. year )
( __õ|õ// ) )Industrial economics and technological management(
_
/ö____/ (_engineering.discipline=Computer::Technology)


~transami

just to throw this out, i’m wondering why placement wasn’t used to
determine scope, just like when you have have variables defined outside
of a block, they are available inside of it, and not local to it. here:

globalvar = ‘global b/c from top level ($)’

class X
X.classvar = ‘class var (@@)’ # perhaps?
instancevar = ‘object instance var (@)’
def x
localvar = ‘local to x’
end
end

i hope no one thinks that i have been trying to push a notion i’ve had
about this, that’s not modus operandi. truly i am just exploring to see
in what ways things might be improved whether that can reasonably happen
or not. for one day i hope to make my own language and in these
discussions i am learning much that i will be able to carry into that.

so, thank you!

···

On Sat, 2002-08-10 at 05:26, Kent Dahl wrote:

Dunno about George, but I consider $ junk and I am very vary of using
@@. Ironically we’re arguing about writer methods inside classes, which
also distances us from the @.

So, while not quite junk, they are ugly, nececarry implementation
details that need to be hidden as soon as possible :slight_smile:


~transami

Hi –

Tom Sawyer wrote:

[George wrote:]

I’d personally rather lose the o.member = ‘something’ notation for method
calling. As David Alan Black mentioned:

Isn’t it good to have to know when you’re calling a method and when
you’re assigning to a local variable :slight_smile:

I didn’t mean that as an anti o.member = ‘x’ argument though :slight_smile: It
was in response to Tom’s having listed needing to know when to write
“self.” among the cons of the variable/method ambiguity. My point was
just that one already knows one is calling a method; there’s no extra
knowledge involved.

so you think writer methods are the problem? what would they be replaced
with?

set_x methods, as is used in most traditional OO languages. They should
still be magically generated using attr_*.

I understand the motive of member=(), though. Since the interface of a
class consists only of methods, o.member = ‘x’ has no meaning, so why not
make that a method too? The problem is when it’s used inside a class, when
you can omit the “o.”, and a gotcha arises from potential ambiguity. I
wonder if simply leaving “o.member = ‘x’” as illegal ruby would’ve been
better.

I would describe it in a different sequence: it’s used inside a
class, you can’t omit the ‘o’, you write the ‘o’, there’s no
ambiguity :slight_smile:

I think one thing that needs to be taken into account is how little
impact this actually has on code – in comparison to the impact there
would be, visually, if every local variable assignment looked
different, or if every “obj.thing = x” became something else.

Here are some rough statistics. The output of /tmp/lines is
the content of all *.rb files in and below ruby/lib, filtering out
“def meth…” lines and comment lines (including block comments).

Local variable assignments:

$ /tmp/lines | grep “(^|[[:blank:]])[a-z_]\w+ *=[^=>~]” | wc
1863 7471 58965

Calls to ‘=’ methods:

$ /tmp/lines | grep “\b\w+.\w+ *=[^=>~]” | wc
195 667 6360

Subset of above, where receiver is explicit “self”:

$ /tmp/lines | grep “\bself.\w+ *=[^=>~]” |wc
34 119 1109

Of course the ratio will vary from one case to another (and I don’t
guarantee the perfection of the filtering or counting :-), but this
suggests strongly to me that having to name the receiver under some
circumstances is a small price to pay for the overall cleanness of
assignment code.

David

···

On Sun, 11 Aug 2002, George Ogata wrote:


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

well, given that there dosen’t seem a reasonable solution to the
ambiguity between local var assignments and standard ruby setter
methods, i am taking kent’s advice, and from this day forward will use
something i picked up from rich kilmer. no longer will i use #var=
setter methods!

i’m creating my own attribute module methods to replace attr_reader,
attr_writer, and attr_accessor. instead of having a seperate method for
assignment, i use the same method as the reader, but it checks to see if
there’s an argument passed. if there is than it acts like a setter.

not positive about the names of these yet, but:

class Module

def Module.attr_rw(name)
name = name.to_s
class_eval <<-EOS
if not method_defined?(:#{name})
def #{name}(*args)
if args.length > 0
return @#{name} = args[0]
else
if @#{name}
return @#{name}
else
return @#{name} = nil
end
end
end
end
EOS
end

def Module.attr_ro(name)
name = name.to_s
class_eval <<-EOS
if not method_defined?(:#{name})
def #{name}
if @#{name}
return @#{name}
else
return @#{name} = nil
end
end
end
EOS
end

end

is this the right way to go about this? can anyone improve on this code?
or see any flaws that need to be fixed? i don’t have a write only
version, do i really need it? i don’t think i’ve have used one before.

given all is well i can now do:

class X
attr_rw :instancevar
def initialize
instancevar ‘i am me’ # set
puts instancevar # get
end
end

···


~transami

Dunno about George, but I consider $ junk and I am very vary of using
@@. Ironically we’re arguing about writer methods inside classes, which
also distances us from the @.

Personally, I disagree. I do a lot of C++ programming with large systems
and one of the first standards we adopted was variable name identification.

This is quite a common thing to do. For example, our C++ classes are named
similar to Ruby consts, our class data members are appended with ‘_’ . We
use setter/getter. And so on.

class TestClass
{

public:

void            var( uint32_t Var );
uint32_t      var() const;

private:

uint32_t    Var_;

};

You get the idea. I was surprised and quite happy to find that Ruby adopts
variable naming as standard. A good idea enforced.

So, while not quite junk, they are ugly, nececarry implementation
details that need to be hidden as soon as possible :slight_smile:

By hiding them you’ll make large bodies of code less readable and allow
people to adopt non-standard solutions to variable naming. This is
something I know from experience.

···


Justin Johnson