W dniu wtorek, 28 stycznia 2014 16:47:53 UTC+1 użytkownik henrik lindberg napisał: > > On 2014-27-01 4:00, Pawel Tomulik wrote: > > Hi, > > > > macros in puppets -> > > http://forge.puppetlabs.com/ptomulik/macro<http://www.google.com/url?q=http%3A%2F%2Fforge.puppetlabs.com%2Fptomulik%2Fmacro&sa=D&sntz=1&usg=AFQjCNGkvKX-MD6afhQeTuuvQSBN4uj0mw> > > > > > > They're similar to parser functions with three differences: > > > > * macro names may resemble names of puppet variables/bindings, e.g. > > 'foo::bar::geez' > > * stored in a hierarchy of directories, that is (for macro > > 'foo::bar::geez'): > > > > + lib/puppet/parser/macros/ > > + foo/ > > + bar/ > > + geez.rb > > > > * they're a little bit easier to implement than functions, because > > arity checking is provided out of the box > > > > In some cases these macros may be more handy than 'params' classes when > > defining defaults for parameters. For example defaults for defined types > > which vary from instance to instance, or values which are hard to be > > computed in puppet DSL may be easily handled with macros. > > > > I have been working on a new API for functions that I hope we will be > able to finish for Puppet 4.0. I have just started and have looked at > the work dalen and zaphod42 did earlier. > > The need for a new API is because the 3x API requires values to be > presented to functions in a particular way (empty strings instead of > undef is one of those). If we want to fix that we do need to have a new > API. I will come back later and present ideas in more detail (I am not > quite done with exploration yet). > > Requirements as I see them: > > * Must be redefinable in different environments / be reloadable > * Support fully qualified names >
Names with '::'? So probably they can't be just module members (or there must be an additional step of registering these methods under fqdn names). > * Support arity (fixed and variable) > It appear that this is quite easy to implement, the idea is just to convert procs/blocks provided by user at definition point to lambas and store lambdas. Basically, I use this code in my implementation of macros: https://gist.github.com/ptomulik/8670700. Of course, if you store puppet functions as a regular methods it becomes even easier. > * Support default arguments > Works only on ruby 1.9+ (at least when we speek in terms of lambdas/procs). On 1.8 `|a=nil|` is a syntax error. > * Support the new type system with automatic type checking > * Support overloading of one function (i.e. multiple signatures) That would be great! And shouldn't be so hard to implement, at least on ruby 1.9+. > > > * Be easy to write for simple functions > The current interface is not so scary, the only scary thing is the need to validate arguments manually, which usually takes 85% of the function's code. If there were dedicated validators, it would be just great! I suppose, most of the work could be done by the type system with automatic type checking (if it's applicable to function arguments). > * Easy to test > So - special rspec helper for functions? > * Callable direct from Ruby > Current functions are actually callable from ruby, aren't they? * Protected from exposure from "too much non API" to reduce future > migration issues > > So far, I am leaning against a design that: > > * Uses regular ruby methods with regular parameter declaration (easier > for users - no need to parse the array args are internally passed). > * One function per ruby file (easier to autoload) > * A call to a newfunction "factory" method that creates the function > class/module internally - thus enabling using anonymous modules > (more or less required to be able to reload/redefine). > * Creation call looks horrible if all the desired features are > to be passed using a hash of options - hence, for more advanced > options, additional methods are implemented. > * Move Functions out of the Puppet::Parser namespace - they are not part > of the parser! > > As an example - here is a simple function from 3x > > Puppet::Parser::Functions::newfunction(:sha1, :type => :rvalue, > :arity => 1, > :doc => "Returns a SHA1 hash value from a provided string.") do > |args| > Digest::SHA1.hexdigest(args[0]) > end > > Rewritten it would be: > > Puppet::Functions.create_function(:sha1) do > # Returns a SHA1 hash value from a provided string. > def sha1(str) > Digest::SHA1.hexdigest(str) > end > end > > If we want to do more - handle multiple signatures, get automatic type > checking etc. Additional calls that defines those are required. > This part is what I am working on now - something along the lines of: > > dispatch(:sha1, 'String[1]') # one arg == non empty string > > (I am leaving out lots of detail here because ideas are half baked) > > I want to be able to: > > * Support simple calls > * Calls to different methods depending on signature > * Support Polymorphic dispatch (based on type of first arg) just > like the future parser/evaluator does. > > I am also contemplating if we want to tie function more closely to > the type of the first argument to allow addition of functions with the > same name that operates on a different type - don't know how valuable > that would be in the Puppet Language though. > > Hope to have a more complete proposal in a couple of weeks time. > > Regards > - henrik > > > > > -- 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 view this discussion on the web visit https://groups.google.com/d/msgid/puppet-dev/73c9c869-69dd-44c9-8ff1-b2fb3d6d56e7%40googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
