how to .call a lamda in OpsCode Chef to be able to do a run time evaluation only?

93 Views Asked by At

I have a question regarding Chef and the Lambda method to evaluate variables rather at run time than compile time. Check the snip below:

md5 = lambda { Digest::MD5.file("#{some_file}").hexdigest }
pp "md5: #{md5}"

This results in:

md5: #<Proc:0x000000000c153b08

But I do want to have the variable itself. What is the exact syntax to .call the lambda and get the actual variable? I am pulling my hair out for days.

Any help highly appreciated!

2

There are 2 best solutions below

1
Stefan On BEST ANSWER

Several options to call a proc or lambda:

md5 = lambda { "foo" }

"md5: #{md5.call}"  #=> "md5: foo"
"md5: #{md5.()}"    #=> "md5: foo"
"md5: #{md5[]}"     #=> "md5: foo"
"md5: #{md5.yield}" #=> "md5: foo"

Each of the above can also accept arguments. This could be used for example to pass the filename: (-> is a lambda proc literal)

md5 = ->(filename) { Digest::MD5.file(filename).hexdigest }

"md5: #{md5.call(somefile)}"
"md5: #{md5.(somefile)}"
"md5: #{md5[somefile]}"
"md5: #{md5.yield(somefile)}"
1
Holger Just On

To evaluate the lambda code, you can call it:

md5 = lambda { Digest::MD5.file("#{some_file}").hexdigest }
pp "md5: #{md5.call}"

The call method of a lambda or generally, a Proc object in Ruby will evaluate the block given when creating the Proc and return the block's return value. Note that the result is not cached and each call invocation will evaluate the block again.