Issue #10505 has been updated by Daniel Pittman.

OK, so first, to the original report:

Welcome to Ruby.  Scope sucks, and that is just fun.  The problem here is that 
`foo` the variable shadows `foo` the function that looks up a Puppet variable.  
To demonstrate, here is the same code in pure Ruby - effectively, what erb 
generates from your template, then some code to demonstrate what actually 
happened:

<pre>
def foo() 42 end
p [foo, defined?(foo)]
if false then
  fail "never get here"
  foo = 1
end
p [foo, defined?(foo)]

# [42, "method"]
# [nil, "local-variable"]
</pre>

When you mention a local variable in Ruby, no matter if the code is evaluated 
or not, you take over that name from then on.  In the case above your 
assignment of `foo = 1` is the reason that the later use of `foo` returns 
"nothing" - the printed version of `nil` - rather than anything else.

I cannot reproduce - or see - any problem with the code if you *don't* try to 
assign to the Puppet "variable" in the template.  Which, frankly, you shouldn't 
be doing anyhow, because that is an invitation to breaking things.  Our 
variables are supposed to be immutable, and using templates to hack around that 
is bad, bad, bad.

Now, the fact that Puppet variables can be shadowed like that?  Ick.  The fact 
that we have other shadowing problems because method looking doesn't shadow 
anything (including fork) from Kernel?  Ick.  All sorts of badness there.

So, ultimately, this isn't a question about us breaking something in a 
template, it is a question about Ruby syntax, and our use of it.
----------------------------------------
Bug #10505: erb mangles if foo == "" and leaves variables undefined
https://projects.puppetlabs.com/issues/10505

Author: Jos Boumans
Status: Investigating
Priority: High
Assignee: Daniel Pittman
Category: templates
Target version: 2.7.x
Affected Puppet version: 2.6.3
Keywords: 
Branch: 


<pre>
$ puppet --version
2.6.3
</pre>

<pre>
$ cat x.pp
define bar ( $foo = "", $zot = "" ) {
  file { '/mnt/tmp/puppet.erb/out':
    content => template( '/mnt/tmp/puppet.erb/tmpl.erb' ),
    ensure => file,
  }
}

bar { $fqdn: foo => "42", zot => "43" }
$ cat tmpl.erb 

foo 1: <%= foo %>
zot 1: <%= zot %>

<% if foo == "" %>
<% foo = 1 %>
<% end %>

foo 2: <%= foo %>
zot 2: <%= zot %>
$ puppet x.pp
notice: /Stage[main]//Bar[cc001.krxd.net]/File[/mnt/tmp/puppet.erb/out]/ensure: 
defined content as '{md5}c776b25cce50fdc968696030b77e9a4d'
$ cat out

foo 1: 42
zot 1: 43



foo 2: 
zot 2: 43
</pre>

################

Confirmed also in 2.7.x, the work around is:
<% foo = scope.lookupvar('foo') || '1' %>



-- 
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