Ambiguity between local variable assignment and writter method

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

Tom Sawyer wrote:

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.

Charles’s points are sensible. My own experience is that I hardly ever
create “setter methods”, only attr_reader methods. This is because my objects
should be changed in ways reflect the grand plan of the object, rather than the
whim of the object’s user in wanting to set some field. And since I don’t
allow the object user to set individual fields, the “@field = value” syntax has
all the convenience without the compromise.

My point is that explicit setter methods can be philosiphized out of existence,
thus rendering the whole “self.field = value” debate academic. To borrow a
phrase from the PickAxe: attr_writer is one of those ideas that looks essential
on paper but isn’t used much in practice.

Of course, that’s just me, and while I think my approach is good, it’s limited
to the kinds of problems I solve, which tend to be nice and small. Thus I
conjecture a second point.

The syntax (for “setter methods”) “object.field = value” implies simplicity.
If you need to jump through various hoops every time a field is written, you
probably want a method that implies it does something serious. Saying
something simple while doing something complicated will likely make code hard
to read. A minor point, perhaps, but one which, if followed, could again take
the sting out of the writer-method-withoud-explicit-self ambiguity.

In short, Ruby offers so many nice features, paradigms, and ease-of-use that
I’m happy to rearrange my “way of doing things” a little to make the code flow
more easily.

[snip some more good arguments]

– Charles Hixson

–Gavin

···

----- Original Message -----
From: “Charles Hixson” charleshixsn@earthlink.net

that’s not a bad option. this way you could actually use @instance=
instead of self.instance= and it would also make for good form.

not as “obvious”, from the programmer’s perspective, as my solution, but
it doesn’t incur a speed hit.

good thinking, rich.

does anyone see any problems with this possibility?

~transami

···

On Fri, 2002-08-09 at 15:19, Rich Kilmer wrote:

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)

Tom Sawyer wrote:

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.

Uh, no, I was thinking:

We already use accessor methods to hide @ away, all the time from the
outside, and also from the inside (which this discussion is mostly
about).

Earlier there has been discussions about @@ vs instance variables of the
class objects. I’m not sure how cumbersome that would be to use though
(in subclasses, you wouldn’t be able to just do type.variable=).

As for $, you use accessor methods on module (or class) objects instead,
effectively giving yourself a namespace for your global variable. I.e.:
module X
def self.x
@x
end
def self.x=(x)
@x=x
end
end
X.x = 5
puts X.x

Defining the methods are akin to declaring the variables, but it sure
beats a $ anyday :slight_smile:

···

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)

Justin Johnson wrote:

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.

I think you misunderstand me. Since you are using setter/getter methods,
you are hiding these details, no? I merely extend this to include
internally in the class: If you have accessor methods, prefer them to
using variables, even when inside methods of the class. If the outside
shouldn’t have write access, make the writer private or protected, don’t
leave it out.

In C++, there is even less fear of using methods instead of variables
directly inside classes, since the performance hit can be removed by
declaring the getter and setter inline.

I am not a proponent of tossing @ out of Ruby.
I’m a proponent of reducing its usage as much as possible in ones own
code.

···


([ 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)

i too tend to think that it is better to have these then not, even
though i understand how they can be viewed as junky, read perly :wink:

curious to know your take on having local variables prefixed as well.

def how(%do, %you)
%feel = ‘about local variables’
%with = ‘prefixes’
puts “#{%do} #{%you}?”
end

:slight_smile:

···

On Mon, 2002-08-12 at 04:07, Justin Johnson wrote:

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.


~transami

This seems more reasonable than “this.”? Wow.

···

— Tom Sawyer transami@transami.net wrote:

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!

=====

Use your computer to help find a cure for cancer: http://members.ud.com/projects/cancer/

Yahoo IM: michael_s_campbell


Do You Yahoo!?
HotJobs - Search Thousands of New Jobs
http://www.hotjobs.com

Hi –

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.

I would recommend:

  1. Don’t check for method existence. Use -w, and let Ruby warn you
    if you’re redefining and/or discarding methods.

  2. Consolidate some of the logic; I don’t think you need that many
    branches. (Or am I overlooking a scenario?)

  3. Consider how you would do the equivalent of this:

    class X
    

    attr_reader :thing
    def thing=(x)
    @thing = “I am #{x}”
    end
    end

    I can’t spot a way to do it very cleanly (i.e., without either
    using aliases and/or manually rewriting the method that was
    automatically written.)

Here’s a somewhat trimmed-down implementation (which I think behaves
the same as yours). I’ve added multi-argument handling.

class Module
def attr_rw(*names)
names.each do |name|
class_eval <<-EOS
def #{name}(*args)
@#{name} = args[0] if args.size > 0
@#{name}
end
EOS
end
end

def attr_ro(*names)
  names.each do |name|
  class_eval <<-EOS
  def #{name}
@#{name}
  end
  EOS
end
end

end

class X
attr_rw :thing, :other
end

x = X.new
x.thing “Hello”
puts x.thing

x.other “Bye”
puts x.other

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

dblack@candle.superlink.net wrote:

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.

I know I was putting it in a different context. I didn’t mean to imply you
were making the same point as me. :slight_smile:

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 was considering the motive from a language design point of view. As in,
“I’m making a funky new flawless language, and I’ve just saved the world
from the evil of public data members. Now what’ve we got to build on?” Or
maybe that was never part of the design process…

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.

Not sure if I get what you mean by “impact” since I was looking at it as a
retrospective curiosity, not as a proposed language change. If set_*
methods would’ve been the norm, I don’t think I could describe it as any
“impact” whatsoever, since it’s a pretty normal thing to do (looking at
other OO languages). member= methods in contrast are unexpected; an
“impact”; a protrusion on an otherwise pretty flat, consistant landscape.
(Not that that’s necessarily bad; protrusion == innovation.)

“Justin Johnson” justinj@mobiusent.com wrote in message
news:3d5783ed$1_8@news.teranews.com

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.

I’d like dot name “.x” instead of “@x” for referencing members.
Incidentally, this is also what the C99 standard adopted. “…x” would then
be a class reference, however, I’d prefer “type.x” or “class.x” over “@@x
or “…x”. “self.x” is an alternative to “.x”.

I wouldn’t have any great problem with “x" or "x”, but I think this is
already part of the name namespace.

As usual I’m probably overlooking some blatantly obvious that prevents this
from being possible.

In C++, Microsoft world tends to use “m_x” for members, I’d personally
prefer “x_” and sometimes “_x” for private (I’m hardly consistent over all
my applications).

Mikkel

Hi –

The syntax (for “setter methods”) “object.field = value” implies
simplicity. If you need to jump through various hoops every time a
field is written, you probably want a method that implies it does
something serious. Saying something simple while doing something
complicated will likely make code hard to read. A minor point,
perhaps, but one which, if followed, could again take the sting out
of the writer-method-withoud-explicit-self ambiguity.

That’s an interesting way to look at it, though I’m not sure it scales
very well. I’m thinking of things like hash-like set and fetch
methods that operate directly (but transparently) on databases, which
I think can be very convenient and not obscure except to the extent
that they’re designed to black-box-ify the file I/O.

I definitely do agree with one part or implication of your point,
namely that #field=() methods should set something. I know that
sounds obvious, but I think part of what feels shaky to people might
be that there’s a disconnect between the presence of assignment syntax
and the question of what’s actually taking place.

David

···

On Tue, 13 Aug 2002, Gavin Sinclair wrote:


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

Tom Sawyer transami@transami.net writes:

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.

that’s not a bad option. this way you could actually use @instance=
instead of self.instance= and it would also make for good form.

The behavior of parent classes would vary if they were subclassed by
classes that defined specific accessors, which might be upsetting.

Dave

Hi –

The syntax (for “setter methods”) “object.field = value” implies
simplicity. If you need to jump through various hoops every time a
field is written, you probably want a method that implies it does
something serious. Saying something simple while doing something
complicated will likely make code hard to read. A minor point,
perhaps, but one which, if followed, could again take the sting out
of the writer-method-withoud-explicit-self ambiguity.

That’s an interesting way to look at it, though I’m not sure it scales
very well. I’m thinking of things like hash-like set and fetch
methods that operate directly (but transparently) on databases, which
I think can be very convenient and not obscure except to the extent
that they’re designed to black-box-ify the file I/O.

You obviously have quite specific requirements in this case that demand a
little exception to my rule (hand on, wasn’t it a conjecture?). I think a nice
access to the database like that sounds good. Even so, I expect these beefy
assignment methods will be nicely contained in one class, and the majority of
classes in your project will be more straightforward in this respect.

Thus I don’t think “scalability” is the problem, just “absolute generality”.

I definitely do agree with one part or implication of your point,
namely that #field=() methods should set something. I know that
sounds obvious, but I think part of what feels shaky to people might
be that there’s a disconnect between the presence of assignment syntax
and the question of what’s actually taking place.

David

Gavin

···

From: dblack@candle.superlink.net

On Tue, 13 Aug 2002, Gavin Sinclair wrote:

by the way, thanks for this david. much nicer than mine --very elegant.
when i get a chance (way too busy at the moment) i’ll investigate your
comments.

~transami

···

On Mon, 2002-08-12 at 10:17, dblack@candle.superlink.net wrote:

class Module
def attr_rw(*names)
names.each do |name|
class_eval <<-EOS
def #{name}(*args)
@#{name} = args[0] if args.size > 0
@#{name}
end
EOS
end
end

def attr_ro(*names)
  names.each do |name|
  class_eval <<-EOS
  def #{name}

@#{name}
end
EOS
end
end
end

could you elaborate on that a touch more? perhaps a small example?

thanks,

~transami

···

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

The behavior of parent classes would vary if they were subclassed by
classes that defined specific accessors, which might be upsetting.

This is how I see it:

class A
def initialize(blah)
@blah = blah
end

def amethod(*args)
	# do things with args
	puts "I don't expect anything special to happen in the next line"
	@blah = ...  # doesn't use accessor as there isn't one
end

end

class B < A
def blah=(thing)
# do something with thing
puts “Hey, doing things in self.blah=, which may be wrong!”
@blah = …
end
end

obj = B.new
obj.amethod(…)

vim: ts=4:

@blah=… inside amethod, defined in class A, will use self.blah=, which
could be wrong if you really need low-level access to the attribute.
amethod expects @blah not to use an accessor, so you’re changing the
behavior of things belonging to the superclass. This isn’t as
if you were overloading a method, since there’s no easy way to avoid
self.blah= being called…

One solution: each method using @attr=… would have to ignore accessors
defined in derived classes. This involves changing the way Ruby looks for
methods, but I don’t think it would be that hard.
This would however make Ruby dirtier, and I don’t quite think I’d like that :expressionless:

···

On Sat, Aug 10, 2002 at 07:07:11AM +0900, Tom Sawyer wrote:

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

The behavior of parent classes would vary if they were subclassed by
classes that defined specific accessors, which might be upsetting.

could you elaborate on that a touch more? perhaps a small example?


_ _

__ __ | | ___ _ __ ___ __ _ _ __
'_ \ / | __/ __| '_ _ \ / ` | ’ \
) | (| | |
__ \ | | | | | (| | | | |
.__/ _,
|_|/| || ||_,|| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

‘Ooohh… “FreeBSD is faster over loopback, when compared to Linux
over the wire”. Film at 11.’
– Linus Torvalds