[Puppet-dev] Re: Macros in puppet
On 2014-27-01 4:00, Pawel Tomulik wrote: Hi, macros in puppets - http://forge.puppetlabs.com/ptomulik/macro 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 * Support arity (fixed and variable) * Support default arguments * Support the new type system with automatic type checking * Support overloading of one function (i.e. multiple signatures) * Be easy to write for simple functions * Easy to test * Callable direct from Ruby * 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 puppet-dev+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/puppet-dev/lc8jes%242gm%241%40ger.gmane.org. For more options, visit https://groups.google.com/groups/opt_out.
[Puppet-dev] Re: Macros in puppet
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/macrohttp://www.google.com/url?q=http%3A%2F%2Fforge.puppetlabs.com%2Fptomulik%2Fmacrosa=Dsntz=1usg=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 *
[Puppet-dev] Re: Macros in puppet
On 2014-28-01 17:29, Pawel Tomulik wrote: W dniu wtorek, 28 stycznia 2014 16:47:53 UTC+1 użytkownik henrik lindberg napisał: 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). Yes, there must be an extra step - the classes must be anonymous. (easy to do), and then bound via a name. (Work remains on how exactly this should work). * 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+. It will be easy to implement using something similar to the polymorphic dispatch used throughout the future parser/evaluator. It cannot be specified using ruby methods directly - it is either implemented with one method where the overaloding logic takes place inside one method, or the user dispatches to different methods depending on signature. (That is the idea anyway). * 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). Yeah, interface is not too bad, but as you say, user is fully responsible for the handling of arguments and their types. * Easy to test So - special rspec helper for functions? I was thinking more about ability to just call it without having to have scopes and stuff. Unfortunately, with an anonymous class it is not as easy as just going MyFunc.call(a,b). Can almost get there though. * Callable direct from Ruby Current functions are actually callable from ruby, aren't they? yes sure, but only after having the Puppet Runtime jumping through hoops adding them to a scope (which requires an environment an a compiler, and known resource types, and...) i.e to get a banana you also get a gorilla and a jungle filled with wildlife. - 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 puppet-dev+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/puppet-dev/lc9hbr%24r99%241%40ger.gmane.org. For more options, visit https://groups.google.com/groups/opt_out.