What is difference in several styles for proc syntax in tcl? - syntax

May I know how sytanx of proc affets on its working.
in context of
-Memory consumption
-Argument passing
-scope of proc (local/global)
proc dosomething {} {
#code here
}
proc dosomething { } {
#code here
}
proc dosomething {
#code here
}
proc dosomething args {
#code here
}
proc ::dosomething {} {
#code here
}
And so on.....

They are mostly the same:
Defines a command with no arguments
proc dosomething {} {
#code here
}
Same as above, defines a command with no arguments
proc dosomething { } {
#code here
}
Not valid... should throw an error
proc dosomething {
#code here
}
Defines a command with a variable number of arguments (ie, varargs)
proc dosomething args {
#code here
}
Defines a command, in the top level namespace, with no arguments (same as the first two in most cases)
proc ::dosomething {} {
#code here
}
There's no such thing as a local proc, btw. They can be inside a namespace, but all procs are global.

Related

Jenkins pipeline multiline script command as variable

how can I save a command in a variable and executed anywhere in the stage
tried differnt way, but still success
here is my example
pipeline {
agent any
environment {
myscript = sh '''
echo "hello"
echo "hello"
echo "hello"
'''
}
stages {
stage("RUN") {
steps {
sh "${myscript}"
}
}
}
}
you can do it like this. Not with a groovy variable but can be more dynamic with groovy function/method
def reusableScript(message) {
sh """
echo Hello World
echo Hi ${message}
"""
}
pipeline {
agent any;
stages {
stage('01') {
steps {
script {
reusableScript("From ${env.STAGE_NAME}")
}
}
}
stage('02') {
steps {
script {
reusableScript("From ${env.STAGE_NAME}")
}
}
}
}
}

Issue with loop in Jenkinsfile

I a variable in my Jenkinsfile that contains a list of URLs and i would like a be able to run over them. When i pass the variable $URL to the function, I get an error:
No such property: $URL for class: groovy.lang.Binding
However, I'm able to echo this variable with sh.
pipeline {
agent any
environment {
URL="https://www.aaa.com," \
+ "https://www.bbb.com," \
+ "https://www.ccc.com"
}
stages {
stage ('A') {
//...
}
stage ('B') {
//...
}
stage ('C') {
steps {
script {
sh 'echo $URL'
funcion($URL)
}
}
}
}
}
def funcion(URL) {
sh "echo Going to echo a list"
for (int i = 0; i < URL.size(); i++) {
sh "echo ${URL[i]}"
}
}
What could be the issue?
You should pass this variable to the funcion() method as
function(URL)
instead of
funcion($URL)
The dollar sign $ is used only inside the GString when you want to interpolate a variable. For instance
#!groovy
def name = "Joe"
println "My name is $name"
results in
My name is Joe
You can read more about string interpolation in the Groovy documentation - http://groovy-lang.org/syntax.html#_string_interpolation

Setting variable outside a block from inside a block?

I have following code:
def test_callback_interface
with_temp_stdio do |stdin, stdout|
stdin.write("hello\n")
stdin.close
stdout.flush
line = nil
replace_stdio(stdin.path, stdout.path) {
Readline.handler_install("> ", true) { |l| line = l }
6.times { Readline.read_char }
Readline.handler_remove
}
assert_equal("hello", line) <------ FAIL here
assert_equal(true, line.tainted?)
stdout.rewind
assert_equal("> ", stdout.read(2))
assert_equal(1, Readline::HISTORY.length)
assert_equal("hello", Readline::HISTORY[0])
end
assert_equal(true, false)
end
it fails on the line assert_equal("hello", line) saying that the line is nil. However, I'm sure that the callback is called (I verified it by putting raise in there). So I must be missing something fundamental about scopes here. Could someone please enlighten me how to get the value of l to the line variable?
Thanks
EDIT:
How do I call the callback inside handler_install/read_char?
static VALUE readline_callback_ensure(VALUE val) {
free(readline_callback_line);
readline_callback_line = NULL;
return Qnil;
}
static VALUE readline_callback_call(VALUE line) {
VALUE proc = rb_attr_get(mReadline, read_char_cb_proc);
rb_funcall(proc, id_call, 1, line);
return Qnil;
}
static void readline_callback_callback(char * line) {
if (readline_callback_add_history && line) {
add_history(line);
}
readline_callback_line = line;
rb_ensure(
readline_callback_call, line ? rb_str_new_cstr(line) : Qnil,
readline_callback_ensure, Qnil
);
}
static VALUE readline_callback_handler_install(int argc, VALUE * argv, VALUE self) {
VALUE tmp, add_hist, block;
char * prompt = NULL;
rb_need_block();
if (rb_scan_args(argc, argv, "02&", &tmp, &add_hist, &block) > 0) {
prompt = RSTRING_PTR(tmp);
}
if (RTEST(add_hist)) {
readline_callback_add_history = true;
} else {
readline_callback_add_history = false;
}
rb_ivar_set(mReadline, read_char_cb_proc, block);
rl_callback_handler_install(prompt, readline_callback_callback);
return Qnil;
}
static VALUE readline_callback_read_char(VALUE self) {
VALUE proc = rb_attr_get(mReadline, read_char_cb_proc);
if (NIL_P(proc)) {
rb_raise(rb_eRuntimeError, "No handler installed.");
}
rl_callback_read_char();
return Qnil;
}
So basically read_char calls rl_callback_read_char (gnu readline function), which on detecting complete line invokes my installed handler readline_callback_callback which invoked stored block supplied by user.
Solved, not an scope issue. GNU Readline calls my code once more with NULL on EOF, complete forgot about that.

Call a method from a Groovy map transformed to a class with asType

Is it possible to call methodTwo() as in
def map = [methodOne: { return "${methodTwo()}" }, methodTwo: { return "Hey" }] as MyInterface
methodTwo cannot be found at runtime by groovy (it seems that it is searching its definition inside the class where the map was defined)
You can call the method declaring the map variable before, and then referencing it:
interface MyInterface {
def methodOne()
def methodTwo()
}
def map
map = [
methodOne: { return "${map.methodTwo()}" },
methodTwo: { return "Hey" }
] as MyInterface
assert map.methodOne() == "Hey"

Store ruby code in a let() variable

I want to store the code will be run inside each_with_index block:
describe '#each_with_index' do
subject { [:a,:b].each_with_index{ block.to_ruby } }
context 'when the block prints v to console' do
let(:block) { '|v| puts v' }
specify { expect { subject }.to output(':a :b').to_stdout }
end
context 'when the block prints i to console' do
let(:block) { '|v,i| puts i' }
specify { expect { subject }.to output('0 1').to_stdout }
end
context 'when the block prints v and i to console' do
let(:block) { '|v,i| puts "#{v} and {i}"' }
specify { expect { subject }.to output(':a and 0 :b and 1').to_stdout }
end
end
I don't need the code stored as a string, it is just a way to show you what I mean. I want to do this with in-block code, pipes, and everything. I've got a feeling we can use Proc.new but the pipes are tripping me up.
Something like:
let(:block) { Proc.new{ |v| puts v } }
subject { [:a,:b].each_with_index { |*args| block.call args } }

Resources