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