Is it possible to use custom function in custom type definition? - puppet

I write module which will define new types. Inside newproperty definition I want to use custom function (also provided in this module) which will munge passed value:
Function
#lib/puppet/parser/functions/my_custom_function.rb
module Puppet::Parser::Functions
newfunction(:my_custom_function, :type => :rvalue) do |args|
...
end
end
Type
#lib/puppet/type/new_type.rb
Puppet::Type.newtype(:new_type) do
newparam(:name) do
munge do |value|
my_custom_function(value)
end
end
end
but I get undefined local variable or method when try use function in type like above.
I also don't have access to stdlib functions inside custom type, but these functions are available in manifest file.
Does someone can provide example how to execute custom function inside type definition especially in munge block?

Custom functions are parser functions, for use in your manifests only.
The type code is used by the agent only, which will not load parser functions while initializing resources.
You will have to duplicate your munging code. If this is not feasible, you may have to implement it in a custom Ruby library, and use that from both within your custom function and your type. The library will need to be installed on both masters and agents in this case.

You need to extract the code from your custom function into a separate location and then call that shared code from both your custom function and from your type/provider. You do not need to pull the code into a separate gem to do this, it is fairly easy to keep the code local to your module.
Put your own Ruby classes in the directory lib/puppet/util/ of your module. You should then be able to require 'puppet/util/my_class' from both your custom function and your type/provider. You can see an example of how I've done this in my module jboss-puppet_admin.

Related

How to refrence a dependancies variable description in terraform?

When writing terraform modules, one is commonly writing pass through variables/inputs for dependent objects.
How can I write the variable so that the description/type just references the dependent description?
I imagine something like
variable "foo" {
type = dependant.resource.foo.var.type
description = dependant.resource.foo.var.description
default = "module default"
}
Variable descriptions are metadata used by Terraform itself (specifically: by documentation mechanisms like Terraform Registry) and are not data visible to your module code.
Each module's input variables and output values must be entirely self-contained. Mechanisms like the Terraform Registry rely on this so that they are able to generate the documentation for a module only by reference to that module, without any need to fetch and analyze any other modules or other dependencies.
If you do intend to have a variable just "pass through" to a child module or to a resource configuration then you will need to redeclare its type and description in your module.
I would also suggest considering the advice in the documentation section When to write a module; directly passing through a variable to a child object isn't necessarily a wrong thing to do, but it can result from a module not raising the level of abstraction and therefore not passing the test described there.
In such cases, it can be better to use module composition instead of nested modules.
In this case would mean that the caller of your module would themselves call the other module you are currently wrapping. Instead of your module taking that other module's input variables as its own, it would be declared to accept the other module's output values as its input, so that the caller can pass the object representing the first module result into the second module:
module "first" {
# ...
}
module "second" {
# ...
first = module.first
}
Inside this "second" module, the input variable first would be declared as requiring an object type with attributes matching whatever subset of the output values of "first" that the second module depends on.

Groovy - Type Check Closure Code Before Execution

I have a Groovy script that lets the user define some dynamic properties and methods and later executes a user-defined closure. A script would look like this:
// init properties and methods dynamically at runtime
context.prop1 = "Some test value"
context.method1 = { String input ->
"exec " + input.toUpperCase()
}
// "this" is set to the context variable from above
run {
println method1( prop1 )
}
So in the beginning of the script, a context is initialized with user-defined properties (e.g. prop1) and methods (e.g. method1). The context is then used as this pointer in the run closure. I have achieved this by dynamically extending the meta class of the context and setting the context as delegate of the run closure (with DELEGATE_FIRST as resolves strategy).
Currently I am struggling at type checking. Before executing the run closure, I would like to check if method1 really expects prop1. I have looked into the DelegatesTo annotation, but that doesn't seem to work for dynamically extended objects. I have also played with the AST, but since my knowledge on that topic is limited, I haven't come up with a solution. If what I want to achieve is possible, any pointers in the right direction would be greatly appreciated.
You want to add a method to a context at runtime and then type check this before execution of that method.
Type checking is done at compile time. That is before anything of your program is executed. There is normally no chance this can ever check anything that will only happen at runtime, unless you have a way to statically declare it and give the compiler the power to do the check. But this means normally, you will have to do static compilation.
One way would be to use type checking extensions, but I think in your case that might be overkill. A more simple way would be to use extension modules. And the most simple way would be to use custom script base class.
But for any of these solution you will need static compilation to really have type checking, same for DelegatesTo (which is more used in combination with extension modules). For a type checked DSL a mix of type checking extensions and extension modules can work very well. But you will of course loose more dynamic features of the language and some simplicity.

Directly calling a function bound to the exports object

I'm reading the cluster.js file of the cluster package and this part confuses me:
fs.readdirSync(__dirname + '/plugins').forEach(function(plugin){
plugin = plugin.replace('.js', '');
exports.__defineGetter__(plugin, function(){
return require('./plugins/' + plugin);
});
});
I know that you can bind objects or functions to the exports object to expose them to different files, but it seems that it is calling a function already bound to the object. However, I always thought you needed to require the file and access functions that way. What is going on here?
This is realization of lazy loading for plugins. Plugin will be loaded only after first access to module property with his name. __defineGetter__ is the 'syntax sugar' not presented in ECMAScript standard. It binds an object's property to a function to be called when that property is looked up.
If a module sets exports to a single function rather than an arbitrary object, then the result of require will be a function reference which can be called directly (note that a function is actually a type of object and as such can have properties, which can also be functions).
That's not what's going on here, though. At the time the code you've shown is executed, a function called __defineGetter__ has already been defined and attached to exports. Here it's simply being called as a method of exports (presumably because the author didn't feel the need to create a redundant local name for it).
i.e. somewhere along the line there's something like
exports.__defineGetter__ = function(propname, getter) {
...
}
Since it doesn't have a local name, the only way to call it is through exports.
Obviously the purpose of the code here is to allow you to call cluster.nameOfPlugin.method(...) without having to manually require each plugin, while not requiring all the possible plugins to be preloaded; instead only the ones you actually use get loaded.

RequireJS - Using both define and require under same function scope

Would like to know is it possible to use both define and require under same function scope. Usually is either require or define, how do I have both under same scope?
define(["my/cart", "my/inventory"],
function(cart, inventory) {
//Define foo/title object in here.
}
);
require(["some/module", "a.js", "b.js"], function(someModule) {
//This function will be called when all the dependencies
//listed above are loaded. Note that this function could
//be called before the page is loaded.
//This callback is optional.
});
The define function is for "defining" modules with dependencies using AMD style, and require is mostly used to call those modules previously defined with define function.
The recommended practice is to define only one module per file, but you can add more than one define if you pass the name of the module as the first argument to that function.
If you pass the name explicitly to the define function you can nest define inside a require call, but it will make no sense, because all the dependencies passed to the require can be passed to the define directly, which is faster an clearer than nesting defines inside requires.
Maybe, nesting a require inside a define could be more useful, perhaps if you have a module with dependencies that are only required under certain conditions, it could make sense to add the common dependencies on the define function, and the more specific ones with a require inside a conditional statement.
In my opinion the important concept is to understand that basically define is for defining AMD modules, and require is for calling them. (you can use non AMD files as dependencies but this is other matter.)

When should I use require() and when to use define()?

I have being playing around with requirejs for the last few days. I am trying to understand the differences between define and require.
Define seems to allow for module separation and allow for dependency ordering to be adhere. But it downloads all the files it needs to begin with. Whilst require only loads what you need when you need it.
Can these two be used together and for what purposes should each of them be used?
With define you register a module in require.js that you can then depend on in other module definitions or require statements.
With require you "just" load/use a module or javascript file that can be loaded by require.js.
For examples have a look at the documentation
My rule of thumb:
Define: If you want to declare a module other parts of your application will depend on.
Require: If you just want to load and use stuff.
From the require.js source code (line 1902):
/**
* The function that handles definitions of modules. Differs from
* require() in that a string for the module should be the first argument,
* and the function to execute after dependencies are loaded should
* return a value to define the module corresponding to the first argument's
* name.
*/
The define() function accepts two optional parameters (a string that represent a module ID and an array of required modules) and one required parameter (a factory method).
The return of the factory method MUST return the implementation for your module (in the same way that the Module Pattern does).
The require() function doesn't have to return the implementation of a new module.
Using define() you are asking something like "run the function that I am passing as a parameter and assign whatever returns to the ID that I am passing but, before, check that these dependencies are loaded".
Using require() you are saying something like "the function that I pass has the following dependencies, check that these dependencies are loaded before running it".
The require() function is where you use your defined modules, in order to be sure that the modules are defined, but you are not defining new modules there.
General rules:
You use define when you want to define a module that will be reused
You use require to simply load a dependency
//sample1.js file : module definition
define(function() {
var sample1 = {};
//do your stuff
return sample1;
});
//sample2.js file : module definition and also has a dependency on jQuery and sample1.js
define(['jquery', 'sample1'], function($,sample1) {
var sample2 = {
getSample1:sample1.getSomeData();
};
var selectSomeElement = $('#someElementId');
//do your stuff....
return sample2;
});
//calling in any file (mainly in entry file)
require(['sample2'], function(sample2) {
// sample1 will be loaded also
});
Hope this helps you.
"define" method for facilitating module definition
and
"require" method for handling dependency loading
define is used to define named or unnamed modules based on the proposal using the following signature:
define(
module_id /*optional*/,
[dependencies] /*optional*/,
definition function /*function for instantiating the module or object*/
);
require on the other hand is typically used to load code in a top-level JavaScript file or within a module should you wish to dynamically fetch dependencies
Refer to https://addyosmani.com/writing-modular-js/ for more information.
require() and define() both used to load dependencies.There is a major difference between these two method.
Its very Simple Guys
Require() : Method is used to run immediate functionalities.
define() : Method is used to define modules for use in multiple locations(reuse).

Resources