On Apr 10, 2013, at 11:50 PM, Peter Meier <[email protected]> wrote:

> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
> 
> Hi Luke,
> 
> thanks for your answer.
> 
>> I'm confident there's an easier way; just the way you're using the 
>> autoloader there seems unecessarily complicated.  Why are you even 
>> using autoloading?  Why don't you just hard-code the invalidator 
>> name, and use normal 'require' or something similar?
> 
> Because the invalidator should be pluggable, means that people should
> be able to deliver their own version of the invalidator in their own
> modules and just configure my terminus to use their implementation of
> the invalidator.
> 
> So as far as my experience goes, I can't simply require a file that is
> delivered by modules, that's why I started using the autoloader, which
> walks through all lib dirs of the modules and loads the found one. Or
> I'm wrong with my understanding how lib code is loaded?
> 
> Distributing the terminus in an own module works well and it's also
> loaded after being configured in routes.yaml. But what's about
> additional code for that terminus, that should also be loaded and
> plugged in based on an own configuration option for that terminus?

The autoloader seemed like a good idea at the time, but over the years we've 
found both that it's often more complicated than you really need, and it 
actively works against you sometimes.  In particular, I think the dev team 
(i.e., not me) is working on fixing some major issues resulting from the fact 
that ruby can't search the module lib dirs.  In other words, the autoloader 
works fine for Puppet plugins, but it works less well for, say, required 
libraries.  In your example, if someone distributed two libraries, and you used 
the autoloader to load one and it tried to use ruby to load the other, you'd 
get a failure.

That isn't to say you shouldn't use it, just that it's not a slam dunk.

Note that if 'require' works, you can require based on passed-in values:

require "path/to/#{library}"

It does look like the autoloader is your best bet at this point, though, and 
the question becomes, how do you the class name.

This is one of those things that always surprised me about ruby: How hard it 
was to convert back and forth between class names and objects.  My solution to 
that in Puppet is, well, to never talk about classes.  You'll notice I just 
about always use things like Puppet::Type.type(:file), instead of 
Puppet::Type::File.

Basically, I built a load+register system for all plugins that load:  Every 
plugin has to register itself with something, and the way you get the class is 
to ask for that registration system.  Notice that you define a type like this:

Puppet::Type.newtype(:foo)

Instead of:

class Puppet::Type::Foo

This is pretty much exactly to avoid the kind of constant munging you're doing.

You're probably right that there's some Puppet code to convert back and forth.  
You might check out puppet/util/constant_inflector.rb, which gets you close.

There's also a bunch of related code in util/classgen.rb, but, um, there be 
dragons.    It's basically a system for loading and managing subclasses of 
things (which, you might have noticed, is a constant pattern in Puppet for 
basically all plugins).  If you're really just loading a terminus, chances are 
that the code you want is already available via classgen and is already usable 
to you, you just need to, well, understand how that system works.

-- 
Luke Kanies | http://about.me/lak | http://puppetlabs.com/ | +1-615-594-8199
Join us at PuppetConf 2013, August 22-23 in San Francisco - 
http://bit.ly/pupconf13

-- 
You received this message because you are subscribed to the Google Groups 
"Puppet Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/puppet-dev?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to