Search code examples
rubyvariableslambdachef-infra

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


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!


Solution

  • 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)}"