I'm using Puppet 4 and I'm wondering how I can pass parameters to another class:
I have a custom resource :
class system::classA {
define myresource ($param1, $param2) {
include system::classB
}
}
class system::classB {
file "${param1}"{
ensure => present
}
}
and I'm calling my resource from another module like
system::classA::myresource {
param1 => "test",
param2 => "test",
}
but the parameters are always empty. How can I pass the parameters or access them in classB?
You need to add the parameters into classB so the data can be passed through:
class system::classB($param1, $param2) {
file { "${param1}":
ensure => present,
}
}
And then instead of using the include function in system::classA::myresource, use this style and set the new parameters:
define myresource ($param1, $param2) {
class { "system::classB":
param1 => $param1,
param2 => $param2,
}
}
(note that it's unusual to a define inside a class, I'd suggest putting myresource outside of classA.)
Related
some times code says it best. In below example code in Chain.add I have the function name and vars fed in to it. But I am trying to reference the object that the function is associated with. How can I do this
class Chainable {
constructor(...values) {
this._chainableConstruct={
name: this.constructor.name,
values
};
}
}
class Chain {
constructor() {
this.data=[];
}
add(func,vars) {
console.log(func.name); //returns fun
console.log(...vars); //returns test 45
console.log(func.parent); //return undefined want object t from line 28
}
}
class Test extends Chainable {
fun() {
console.log("fun");
}
}
let t=new Test();
let c=new Chain();
c.add(t.fun,["test",45]);
Out of the box, you can't. Furthermore, you can set property values of multiple objects with the same value, so the same function object might have multiple "parents".
I have an app.js with this code:
var addnote = (title,body) => { /* enter code here */ }
module.exports = {addnote};
Can I add another addnotes function with different parameters to that file?
Function overloading in JavaScript does not exist like in other programming languages such as C# and Java.
What you should be looking to do is pass an object as a parameter that has properties attached and filter them out there..
You could call different functions from your little 'mapping function' just implement the logic there if it isn't big (to keep the code clear).
function foo(parameters){
var title = parameters.title;
var body = parameters.body;
if(parameters.extraProperty){
// oh we have extraProperty passed in too, run a different function?
bar(title, body, parameters.extraProperty); // ??
}
}
foo({title: 'Title', body: 'Body', extraProperty: 'This is extra...'});
If this is your own custom module, you can use the concept of function overriding, where each child class can have its own way to handle something and also have a default way to do things.
class Parent {
constructor(name) {
this.name = name;
}
greet() {
console.log(`Hello ${this.name}`);
}
}
class Child1 extends Parent {
constructor(name) {
super(name);
}
greet() {
console.log(`Hey there ${this.name}. This is Child 1`);
}
}
class Child2 extends Parent {
constructor(name) {
super(name);
}
greet() {
console.log(`Hi there ${this.name}. This is Child 2`);
}
}
const o1 = new Child1('Foo')
const o2 = new Child2('Foo')
o1.greet();
o2.greet();
But if you are trying to override a function in an external module(You do not have access to that code, like a library), my suggestion is to create a wrapper and add functionality there.
I'm trying to write a Jenkins Job DSL script and would like to write it as declaratively / DRY-ly as possible. The Jenkins task is calling some other tasks via a MultiJob. I have Groovy that originally looks like this (everything's contained within a class because it's referenced elsewhere):
static void buildDownstream(def parentJob, String commit_a="master",
String commit_b="master") {
parentJob.with {
steps {
phase('Phase') {
job("name_1") {
prop('COMMIT_A', commit_a)
nodeLabel('NODE_LABEL', NODE_LABEL_MAP["name_1"])
killPhaseCondition('NEVER')
}
job("name_2") {
prop('COMMIT_A', commit_a)
prop('COMMIT_B', commit_b)
nodeLabel('NODE_LABEL', NODE_LABEL_MAP["name_2"])
killPhaseCondition('NEVER')
}
job("name_3") {
prop('COMMIT_A', commit_a)
prop('COMMIT_B', commit_b)
nodeLabel('NODE_LABEL', NODE_LABEL_MAP["name_3"])
killPhaseCondition('NEVER')
}
}
}
}
}
I'd like to abstract out the job creation, which contains lots of duplication. I've ended up with something strange like this:
static void buildDownstream(def parentJob, String commit_a="master",
String commit_b="master") {
parentJob.with {
steps {
phase('Phase') {
def phase = ({ owner })();
{ ->
add_node_label=true;
{ ->
commit_a = null;
def self = ({ owner })();
addJob("name_1", self).call(phase);
}
def self = ({ owner })();
addJob("name_2", self).call(phase);
addJob("name_3", self).call(phase);
}
}
}
}
}
private static Closure addJob(String job_name, Closure callingClosure) {
return { phase ->
def job_config = {
if(commit_a != null) {
prop('COMMIT_A', commit_a)
}
if(commit_b != null) {
prop('COMMIT_B', commit_b)
}
if(add_node_label == true) {
nodeLabel('NODE_LABEL', NODE_LABEL_MAP[job_name])
}
killPhaseCondition('NEVER')
}
job_config.delegate = callingClosure
job_config.resolveStrategy = Closure.DELEGATE_ONLY
phase.job(job_name, job_config)
}
}
which, probably being totally non-idiomatic Groovy (all this def self = ({ owner })() stuff doesn't sit right with me), doesn't work at all.
Basically, I want to pass all the variables in callingClosure's scope to the job_config closure without explicitly passing all of them in as arguments. (Explicitly passing a map of arguments works, but it gets unwieldy when there are lots of arguments.) How can I do this?
(P.S: Currently, Groovy is trying to resolve the commit_a variable inside job_config as coming from javaposse.jobdsl.dsl.helpers.step.PhaseContext, which I find strange; didn't I explicitly set the delegate to a closure inside that PhaseContext?)
EDIT: From another SO question, it appears that I can set phase = delegate (which defaults to owner?) instead of ({ owner })() and be fine; I don't really get this either, since job is a property of the PhaseContext, and not its parent (?)
Well, I ended up not trying to ask Groovy to implicitly resolve variables from the delegate context, and instead just passed in the parameters in a map.
static void buildDownstream(def parentJob,
String commit_a="master", String commit_b="master") {
parentJob.with {
steps {
phase('Tests') {
def params = [COMMIT_A:commit_a]
this.getTestJob(delegate, "name_1", params)
params.COMMIT_B = commit_b
this.getTestJob(delegate, "name_2", params)
this.getTestJob(delegate, "name_3", params)
continuationCondition('ALWAYS')
}
}
}
}
private static void getTestJob(def phase, String job_name,
Map properties) {
phase.job(job_name) {
properties.each { k, v -> prop(k, v) }
killPhaseCondition('NEVER')
}
}
One problem with my original method was that I was trying to access local variables in the closures, but that requires the closure to be evaluated; that turns out to be really weird, and I guess I should just not try to do that.
I have such problem :
there is some method
private List<int> GetStatusList()
{
return (List<int>)GetValue(getSpecifiedDebtStatusesProperty);
}
To invoke it in main thread - I use
`delegate List<int> ReturnStatusHandler();` ...
this.Dispatcher.Invoke(new ReturnStatusHandler(GetStatusList));
How can I do the same, using lambda expression instead of custom delegate and method?
you can pass this:
new Action(GetStatusList)
or
(Action)(() => { GetStatusList; })
You can avoid explicit casting by creating a simple method:
void RunInUiThread(Action action)
{
Dispatcher.Invoke(action);
}
Use this as follows:
RunInUiThread(() =>
{
GetStatusList();
});
I have simple Groovy category class which adds method to String instances:
final class SampleCategory {
static String withBraces(String self) {
"($self)"
}
}
I want to use this category in my unit tests (for example). It looks like this:
class MyTest {
#Test
void shouldDoThis() {
use (SampleCategory) {
assert 'this'.withBraces() == '(this)'
}
}
#Test
void shouldDoThat() {
use (SampleCategory) {
assert 'that'.withBraces() == '(that)'
}
}
}
What I'd like to achieve, however, is ability to specify that category SampleCategory is used in scope of each and every instance method of MyTest so I don't have to specify use(SampleCategory) { ... } in every method.
Is it possible?
You can use mixin to apply the category directly to String's metaClass. Assign null to the metaClass to reset it to groovy defaults. For example:
#Before void setUp() {
String.mixin(SampleCategory)
}
#After void tearDown() {
String.metaClass = null
}
#Test
void shouldDoThat() {
assert 'that'.withBraces() == '(that)'
}
Now you have the option to use extension modules instead of categories:
http://mrhaki.blogspot.se/2013/01/groovy-goodness-adding-extra-methods.html
On the plus side Intellij will recognize the extensions. I've just noticed that it doesn't even need to be a separate module as suggested by the link, just add META-INF/services/org.codehaus.groovy.runtime.ExtensionModule to the project:
# File: src/main/resources/META-INF/services/org.codehaus.groovy.runtime.ExtensionModule
moduleName = module
moduleVersion = 1.0
extensionClasses = SampleExtension
The extension class is pretty much defined like a normal category:
class SampleExtension {
static String withBraces(String self) {
"($self)"
}
}
Can be used like:
def "Sample extension"() {
expect: 'this'.withBraces() == '(this)'
}
If you are using Spock there is a #Use annotation that can be used on the specifications. The drawback with that is that Intellij will not recognize it.