Solutions for deep class paths

Hi all,

I've currently got a very flat code structure in a large code base[1], and I'm looking at redoing the layout to make the functional lines more obvious. This redesign will add an extra constant to every class path; e.g., where I might have 'Puppet::Type::User' right now, I'd have 'Puppet::OSAL::Type::User' in the new layout.

If possible, I'd like to avoid having to type full class paths every time I talk about a class. I've noticed that Ruby behaves very differently depending on how I define a class; for instance:

class One
   class Two
   end
end

will allow Two to use unqualified constants from One, but

class One::Two
end

will not. This is fine for shallow class paths, but it gets annoying when every single class I define has to look like this:

module Puppet
   module OSAL
     class Type
       class User
       ...
       end
     end
   end
end

I'd *much* prefer to just write:

module Puppet::OSAL::Type::User
end

But if I do that, then I'll always have to specify the full class path. I have quite a few classes in Puppet, and having to include the full wrappers for every constant in the class path would get very painful, and I would have to be very conscious of load order (because every class in Puppet::OSAL::Type would either have to specify type's parent class if there is one, or it would have to be loaded after Puppet::OSAL::Type was loaded).

Are there semi-standard ways of making deep class paths more convenient to use?

Thanks,
Luke

1 - http://reductivelabs.com/projects/puppet

···

--
  Someday I want to be rich. Some people get so rich they lose all
  respect for humanity. That's how rich I want to be. --Rita Rudner
  ---------------------------------------------------------------------
  Luke Kanies | http://reductivelabs.com | http://madstop.com

On Jan 17, 10:26 am, Luke Kanies <l...@madstop.com> wrote, in part:

This is fine for shallow class paths, but it gets annoying
when every single class I define has to look like this:

module Puppet
   module OSAL
     class Type
       class User
       ...
       end
     end
   end
end

I'd *much* prefer to just write:

module Puppet::OSAL::Type::User
end

module Puppet; module OSAL; class Type
  class User
    ...
  end
end

That's all I can think of.

Cheers,
Gavin

Can you group all the constants in a module? Something like this:

module Puppet

   module Constants
     Constant1 = 42
     Constant2 = Constant1 * 42
   end

   module OSAL
     module Type
     end
   end

   class OSAL::Type::User
     include Constants # Now the constants can be used unqualified

     puts Constant1
   end

   class OSAL::Type::User2
     include Constants # Now the constants can be used unqualified

     puts Constant2
   end
end

Gary Wright

···

On Jan 16, 2007, at 6:26 PM, Luke Kanies wrote:

I'd *much* prefer to just write:

module Puppet::OSAL::Type::User
end

But if I do that, then I'll always have to specify the full class path.

This still requires a bunch of end statements:

module Puppet; module OSAL; class Type
   class User
   ...
   end
end; end; end

Not the worst, I guess, but it'd be nice if I could just manipulate the constant lookup path or something.

···

On Jan 17, 2007, at 12:20 PM, Gavin Sinclair wrote:

module Puppet; module OSAL; class Type
  class User
    ...
  end
end

That's all I can think of.

  --
  The time to repair the roof is when the sun is shining.
          -- John F. Kennedy
  ---------------------------------------------------------------------
  Luke Kanies | http://reductivelabs.com | http://madstop.com

Well, the constants in this case are all of the class constants, not arbitrary constants like numbers. So, if I did this, I'd have to stick a constant for each class into that Constants module.

···

On Jan 17, 2007, at 2:39 PM, gwtmp01@mac.com wrote:

Can you group all the constants in a module? Something like this:

module Puppet

  module Constants
    Constant1 = 42
    Constant2 = Constant1 * 42
  end

  module OSAL
    module Type
    end
  end

  class OSAL::Type::User
    include Constants # Now the constants can be used unqualified

    puts Constant1
  end

  class OSAL::Type::User2
    include Constants # Now the constants can be used unqualified

    puts Constant2
  end
end

  --
  Risk! Risk anything! Care no more for the opinions of others, for those
  voices. Do the hardest thing on earth for you. Act for yourself. Face
  the truth. -- Katherine Mansfield
  ---------------------------------------------------------------------
  Luke Kanies | http://reductivelabs.com | http://madstop.com

If each class has its own collection of constants, why aren't you putting the definitions right in the class? In your original post it sounded like you were looking for a way to have several different classes have 'direct' access to a common collection of constants (i.e. without the need for explicit scoping).

Gary Wright

···

On Jan 16, 2007, at 11:21 PM, Luke Kanies wrote:

Well, the constants in this case are all of the class constants, not arbitrary constants like numbers. So, if I did this, I'd have to stick a constant for each class into that Constants module.

Well, that's kind of what I want, except that in this case the constants are those associated with my classes and modules. E.g., the constants in question are 'Puppet' (which points to the Puppet module) and Puppet::OSAL::Type (which points to the Type class in Puppet::OSAL).

There's probably a better way to talk about this, I suppose. What I really want is to have access to all of the classes in Puppet without having to specify quite so long a constant path everywhere and also without having to have all of my classes wrapped in four or five module/end statements.

···

On Jan 17, 2007, at 3:46 PM, gwtmp01@mac.com wrote:

On Jan 16, 2007, at 11:21 PM, Luke Kanies wrote:

Well, the constants in this case are all of the class constants, not arbitrary constants like numbers. So, if I did this, I'd have to stick a constant for each class into that Constants module.

If each class has its own collection of constants, why aren't you putting the definitions right in the class? In your original post it sounded like you were looking for a way to have several different classes have 'direct' access to a common collection of constants (i.e. without the need for explicit scoping).

  --
  If a dog jumps onto your lap it is because he is fond of you; but if a
  cat does the same thing it is because your lap is warmer.
                  -- Alfred North Whitehead
  ---------------------------------------------------------------------
  Luke Kanies | http://reductivelabs.com | http://madstop.com

Luke Kanies <luke <at> madstop.com> writes:

and also
without having to have all of my classes wrapped in four or five
module/end statements.

Personally, I don't see this as a bad thing. I would say it's a good idea to use
nesting to show, uh, how classes and modules are nested. In any case, it only
happens once per file.