Issue #10547 has been updated by Daniel Pittman.

Category set to language
Status changed from Unreviewed to Accepted
Assignee set to Randall Hansen
Keywords set to ruby dsl

Matthew Black wrote:
> I figured out a work around, which might be the solution instead of a bug, 
> which is to do this
> 
> `:content => inline_template([temp])`
> 
> It is different behavior than the Puppet DSL counter part.

Actually, that is identical behaviour to the Puppet DSL counterpart - it just 
*looks* different, because the Puppet DSL transparently wraps any argument in 
an array.

Thanks to the wonders of Ruby, though, there are some extra magic bits that 
make this extra-specially confusing:

The parser function is declared with a block taking a single argument, `vals`.  
With Ruby 1.9.2 or later this result in an `inline_template` function that 
accepts one and only one argument.  With the Ruby 1.8 series, if you define a 
method from a block, and that block takes a single argument, Ruby transparently 
makes that an implicit `*vals` argument - it collects multiple arguments and 
turns them into an array, but only if you have more than one.

That means we have exciting DSL behaviour differences in that 
`inline_template(part1, part2)` will actually work as expected for a template 
with embedded newlines in Ruby 1.8, but it won't with a single argument, 
because...

...the implementation uses `vals.collect` to iterate over the array of 
templates supplied, compiling each one, and then concatenates the result at the 
far end.

For the Puppet DSL use case this means that you get one or more strings in an 
array, and everything works as expected.

When the Ruby DSL invokes the method "incorrectly" - in the way that is natural 
from Ruby, but not actually what Puppet expects - you get the effect of calling 
String#collect, not Array#collect, which is implicitly 
`String.split("\n").collect`, and so tries to process every line of your input 
string as an independent template.

Fun fact, if you had newlines, but didn't have any constructs that split 
template stuff over lines, it would work just fine.  So, not only is this an 
awesome way to mess with people, it is a very difficult problem to build a 
mental model about the failure states of if you don't read the implementation 
*and* know a bunch about how Ruby handles these objects.

This can be partly fixed by changing the method to work nicely from both the 
Ruby and Puppet DSL, but we should probably change the entire function calling 
prototype model that we use so that this doesn't hit, eg, user defined parser 
functions in the same way.
----------------------------------------
Bug #10547: inline_template newlines issue with ruby dsl
https://projects.puppetlabs.com/issues/10547

Author: Matthew Black
Status: Accepted
Priority: Normal
Assignee: Randall Hansen
Category: language
Target version: 
Affected Puppet version: 
Keywords: ruby dsl
Branch: 


When using an inline template, it does not like multiline statements.

The following example will throw an erb error when the master tries to compile 
it.

node "default" do
        temp = "<% scope.to_hash.keys.each do |k| %>\n<%= k %>\n<% end %>"
        file '/tmp/test.txt',
                :content => inline_template(temp)
end

If there are no newlines it will compile without issue.


-- 
You have received this notification because you have either subscribed to it, 
or are involved in it.
To change your notification preferences, please click here: 
http://projects.puppetlabs.com/my/account

-- 
You received this message because you are subscribed to the Google Groups 
"Puppet Bugs" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/puppet-bugs?hl=en.

Reply via email to