Using underscores for "private" instance variables?

J

Jeff

I noticed that Rails core is adopting a style of using an underscore
at the start of an ivar name, like @_env. (see the short thread at
http://groups.google.com/group/rubyonrails-core/browse_thread/thread/a45de7e435c6c22a)

I kind of hate leading underscores. They remind me of my C++
days :) The reasoning sounds logical enough: for ivars that are
supposed to be "private" the class/module, it helps avoid naming
conflicts with client code that includes/derives from that module or
class that wants to keep "it's own" ivars.

But I haven't seen anyone else need to do this in their modules/
classes, so now I'm wondering - has anyone else needed to do this? It
seems like this would be a common problem for any shared Ruby library,
so now I'm wondering why I *haven't* run into this before.

Jeff
 
G

Gregory Brown

But I haven't seen anyone else need to do this in their modules/
classes, so now I'm wondering - has anyone else needed to do this? =A0It
seems like this would be a common problem for any shared Ruby library,
so now I'm wondering why I *haven't* run into this before.

As things get sufficiently, complex, I think that something like this
might be reasonable. Prawn is edging on needing some support for
avoiding name clashes, since it carries a lot of internal state in the
Document class and utilizes many mixins.
I'm not sure if this is the convention we'll use, but it's one possibility.
 
D

Daniel Berger

As things get sufficiently, complex, I think that something like this
might be reasonable. =A0 Prawn is edging on needing some support for
avoiding name clashes, since it carries a lot of internal state in the
Document class and utilizes many mixins.
I'm not sure if this is the convention we'll use, but it's one possibilit=
y.

I brought up using underscores a long time ago. :)

http://aspn.activestate.com/ASPN/Mail/Message/ruby-talk/2305779

Regards,

Dan
 
J

Jeff

As things get sufficiently, complex, I think that something like this
might be reasonable. =A0 Prawn is edging on needing some support for
avoiding name clashes, since it carries a lot of internal state in the
Document class and utilizes many mixins.
I'm not sure if this is the convention we'll use, but it's one possibilit=
y.

Gregory, that's interesting. Maybe any Ruby library that reaches
sufficent mass use will run into this problem.

But I think the underscore doesn't really solve the problem, right?

Let's say you use @_file in your module that I include. You probably
use #nodoc# around it so I don't even see it in the rdocs. So then my
class I'm about to do @file, but I think, someone might derive from my
class, so I'd better call it @_file. Collision again.

So I say, let's not use the hard-to-read underscores, and document
ivars in the rdocs like everything else.

Of course, it's not that I like my solution either... :-( I'm just
not seeing how adding underscores solves the problem.

Jeff
 
G

Gregory Brown

On Jan 12, 9:48=A0am, Gregory Brown <[email protected]> wrote:
Gregory, that's interesting. =A0Maybe any Ruby library that reaches
sufficent mass use will run into this problem.

But I think the underscore doesn't really solve the problem, right?

Let's say you use @_file in your module that I include. =A0You probably
use #nodoc# around it so I don't even see it in the rdocs. =A0So then my
class I'm about to do @file, but I think, someone might derive from my
class, so I'd better call it @_file. =A0Collision again.

In either case, it's your fault if you don't read upstream source.
But if you're trying to make life easier downstream, it's less likely
to clash with @_file than it is with @file by accident.

But I agree, @_whatever is ugly and I'm not sure I will introduce it
into Prawn. I just understand why the Rails guys did it after having
a bit of direct experience.
So I say, let's not use the hard-to-read underscores, and document
ivars in the rdocs like everything else.

I don't think that internal state benefits from public documentation,
as that just invites one more thing that can get out of date fast, and
invites more danger than it's worth.

I think one real solution is to avoid ivar references in modules
(using method calls), and prefer composition over sub-classing. But
this is edging on the sort of discipline you'd find in functional
languages, which tends to feel a bit too stuffy for some folks.

I'm about to do some major refactoring in Prawn in the near future. I
might play with these thoughts and see where they lead. If I shake
anything loose that's worth sharing, I'll write it up on the RBP blog.

-greg
 
M

Martin Boese

=20
Gregory, that's interesting. Maybe any Ruby library that reaches
sufficent mass use will run into this problem.
=20
But I think the underscore doesn't really solve the problem, right?
=20
Let's say you use @_file in your module that I include. You probably
use #nodoc# around it so I don't even see it in the rdocs. So then my
class I'm about to do @file, but I think, someone might derive from my
class, so I'd better call it @_file. Collision again.
=20
So I say, let's not use the hard-to-read underscores, and document
ivars in the rdocs like everything else.
=20
Of course, it's not that I like my solution either... :-( I'm just
not seeing how adding underscores solves the problem.
=20
Jeff

I don't think it's about avoiding name clashes but a kind of 'Hungarian
Notation': When looking at a variable name you immediately see it's
intention. No need to browse any rdoc or check when it was first
initialized. I sometimes name variables with an underscore if they are
not intended to be accessed from the outside via attr, attr_reader etc..

martin
 
C

Colin Bartlett

But I agree, @_whatever is ugly and I'm not sure I will introduce it
into Prawn. =A0 I just understand why the Rails guys did it after having
a bit of direct experience. ...
I'm about to do some major refactoring in Prawn in the near future.
I might play with these thoughts and see where they lead. =A0 If I shake
anything loose that's worth sharing, I'll write it up on the RBP blog.

Sorry for being a bit late to this thread.
Date (from the 2008-01-17 version?) seems to use @__ca__
as a "hidden" cache for some values:
def initialize(ajd=3D0, of=3D0, sg=3DITALY)
@ajd, @of, @sg =3D ajd, of, sg
@__ca__ =3D {}
end
Are there any reasons you can't use a hash like that,
or maybe use something like the code below?
Admittedly, the underlying problem isn't eliminated,
just reduced: one has to "agree" not to use @_
(or something similar if @_ is in use or "reserved" for
future use) for a "normal" attribute.
And things like @_.pa2 aren't pretty.
But one thing I like about Ruby is that some things
aren't forbidden, just discouraged by looking ugly
and/or being difficult, so you must think carefully
before using them.

class ExampleClass
class PrivateAtts
attr_accessor :private_attribute_1, :pa2
end
def initialize() ; @_ =3D PrivateAtts.new ; end
def a_method( n ) ; @_.pa2 =3D n ; end
def another_method() ; @_.pa2 ; end
end

ex =3D ExampleClass.new
#=3D> #<ExampleClass:0x2650600 @_=3D#<ExampleClass::privateAtts:0x26505e0>>
ex.a_method(42)
#=3D> #<ExampleClass:0x2650600 @_=3D#<ExampleClass::privateAtts:0x26505e0 @=
pa2=3D42>>
ex.another_method()
#=3D> 42
 

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

Forum statistics

Threads
473,777
Messages
2,569,604
Members
45,234
Latest member
SkyeWeems

Latest Threads

Top