Using underscores for "private" instance variables?

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 :slight_smile: 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

On Tue, Jan 12, 2010 at 10:33 AM, Jeff [email protected] wrote:

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.

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.

On Jan 12, 8:48 am, Gregory B. [email protected] wrote:

I’m not sure if this is the convention we’ll use, but it’s one possibility.
I brought up using underscores a long time ago. :slight_smile:

Regards,

Dan

On Tue, Jan 12, 2010 at 9:11 PM, Jeff [email protected] wrote:

On Jan 12, 9:48 am, Gregory B. [email protected] wrote:

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.

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

On Wed, 13 Jan 2010 11:11:34 +0900
Jeff [email protected] wrote:

for avoiding name clashes, since it carries a lot of internal state
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… :frowning: I’m just
not seeing how adding underscores solves the problem.

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

On Jan 12, 9:48 am, Gregory B. [email protected] wrote:

I’m not sure if this is the convention we’ll use, but it’s one possibility.
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… :frowning: I’m just
not seeing how adding underscores solves the problem.

Jeff

On Wed, Jan 13, 2010 at 4:24 AM, Gregory B.
[email protected] wrote:

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.
…
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.

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=0, of=0, sg=ITALY)
@ajd, @of, @sg = ajd, of, sg
@ca = {}
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() ; @_ = PrivateAtts.new ; end
def a_method( n ) ; @.pa2 = n ; end
def another_method() ; @
.pa2 ; end
end

ex = ExampleClass.new
#=> #<ExampleClass:0x2650600 @=#ExampleClass::PrivateAtts:0x26505e0>
ex.a_method(42)
#=> #<ExampleClass:0x2650600 @
=#<ExampleClass::PrivateAtts:0x26505e0
@pa2=42>>
ex.another_method()
#=> 42