Using underscores for "private" instance variables?

Discussion in 'Ruby' started by Jeff, Jan 12, 2010.

  1. Jeff

    Jeff Guest

    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
     
    Jeff, Jan 12, 2010
    #1
    1. Advertising

  2. On Tue, Jan 12, 2010 at 10:33 AM, Jeff <> 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? =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.
     
    Gregory Brown, Jan 12, 2010
    #2
    1. Advertising

  3. On Jan 12, 8:48=A0am, Gregory Brown <> wrote:
    > On Tue, Jan 12, 2010 at 10:33 AM, Jeff <> 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? =A0I=

    t
    > > 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. =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
     
    Daniel Berger, Jan 12, 2010
    #3
  4. Jeff

    Jeff Guest

    On Jan 12, 9:48=A0am, Gregory Brown <> wrote:
    > On Tue, Jan 12, 2010 at 10:33 AM, Jeff <> 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? =A0I=

    t
    > > 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. =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
     
    Jeff, Jan 13, 2010
    #4
  5. On Tue, Jan 12, 2010 at 9:11 PM, Jeff <> wrote:
    > On Jan 12, 9:48=A0am, Gregory Brown <> 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
     
    Gregory Brown, Jan 13, 2010
    #5
  6. Jeff

    Martin Boese Guest

    On Wed, 13 Jan 2010 11:11:34 +0900
    Jeff <> wrote:

    > On Jan 12, 9:48=C2=A0am, Gregory Brown <> wrote:
    > > On Tue, Jan 12, 2010 at 10:33 AM, Jeff <> 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? =C2=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. =C2=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
    > > possibility.

    >=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
     
    Martin Boese, Jan 13, 2010
    #6
  7. On Wed, Jan 13, 2010 at 4:24 AM, Gregory Brown
    <> wrote:
    > 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
     
    Colin Bartlett, Jan 22, 2010
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Laura
    Replies:
    1
    Views:
    413
    Laura
    Jun 3, 2004
  2. J. Hall
    Replies:
    4
    Views:
    1,148
    J. Hall
    Jun 3, 2004
  3. Jeremy Bowers
    Replies:
    3
    Views:
    532
    Steven Bethard
    Jan 24, 2005
  4. Gregor Kofler
    Replies:
    6
    Views:
    218
    Gregor Kofler
    Jun 27, 2008
  5. Brett
    Replies:
    5
    Views:
    75
    Brett
    Jan 27, 2009
Loading...

Share This Page