template and scope

21 views
Skip to first unread message

Fabrice Bacchella

unread,
May 26, 2014, 12:40:36 PM5/26/14
to puppet...@googlegroups.com
I wrote the following manifest :

===============================
define mysubtype($filepath = $title, $source) {
file {"$filepath":
content => template("$source")
}
}

define mytype($param2) {
mysubtype{"/tmp/parsed1":
source => "/tmp/parsed.erb"
}
file{"/tmp/parsed2":
content => template("/tmp/parsed.erb"),
}
}

class myclass($param1) {
mytype{'mytype':
param2 => "param2"
}
}

class {"myclass":
param1 => "param1"
}
===============================


parsed.erb is :
===============================
<% require "yaml" %>
<%= YAML::dump(scope.to_hash) %>
===============================

So the template for file parsed2 is called directly, but file for template parse1 goes through a custom type.

After a puppet apply, a diff betwen /tmp/parsed1 and /tmp/parsed2 gives : (< is file parsed1, > is file parsed2)
===============================
45c45
< title: /tmp/parsed1
---
> title: mytype
66d65
< source: /tmp/parsed.erb
85a85
> param2: param2
91c91
< name: /tmp/parsed1
---
> name: mytype
105d104
< filepath: /tmp/parsed1
===============================

Is that normal that params1 is part of the context in both case, but not param2 ?

I think the value of 'title' and name disturbing too. It should be either mysubtype and mytype or /tmp/parsed1 and /tmp/parsed2. But no a strange mix of both.

For completness :
$ facter puppetversion rubyversion lsbdistdescription
lsbdistdescription => Scientific Linux release 6.5 (Carbon)
puppetversion => 3.6.1
rubyversion => 1.8.7

Felix Frank

unread,
May 27, 2014, 7:53:29 AM5/27/14
to puppet...@googlegroups.com
On 05/26/2014 06:40 PM, Fabrice Bacchella wrote:
> Is that normal that params1 is part of the context in both case, but not param2 ?

Ugh. Scope semantics. It *does* seem a little weird. Here's my take:

1. $param1 is a local variable (a parameter) of myclass
2. Mytpe[mytype] is scoped into myclass
3. Mysubtype[/tmp/parsed1] is inheriting this scope from its enclosing
defined type

I will have to assume that defined types don't incur another level of
scoping of their own.

Then it kind of makes sense.

> I think the value of 'title' and name disturbing too. It should be either mysubtype and mytype or /tmp/parsed1 and /tmp/parsed2. But no a strange mix of both.

Uhm, no.

Your template is evaluated from inside these defined type instances:
Mytpe[mytype]
Mysubtype[/tmp/parsed1]

Therefor $name and $title *must* take the values 'mytype' and
'/tmp/parsed1' respectively. Anything else would be quite inconsistent.

HTH,
Felix

jcbollinger

unread,
May 27, 2014, 10:40:57 AM5/27/14
to puppet...@googlegroups.com


On Tuesday, May 27, 2014 6:53:29 AM UTC-5, Felix.Frank wrote:
On 05/26/2014 06:40 PM, Fabrice Bacchella wrote:
> Is that normal that params1 is part of the context in both case, but not param2 ?

Ugh. Scope semantics. It *does* seem a little weird. Here's my take:


I don't think it's even weird, once you understand that Puppet does not have nested scopes.  It has global scope and local scopes, and on the DSL side it has a mechanism for consulting a hierarchy of multiple scopes (based on name components, not on lexical nesting or declaration chains) to resolve relative names.

The Puppet variables available in a template directly from the scope object are the locals of the scope from which template() or inline_template() was called, plus (I think) the globals that are not shadowed by locals.


Your template is evaluated from inside these defined type instances:
Mytpe[mytype]
Mysubtype[/tmp/parsed1]



That is exactly the key.

 
Therefor $name and $title *must* take the values 'mytype' and
'/tmp/parsed1' respectively. Anything else would be quite inconsistent.



Quite so.  And it's not just a question of consistency -- it's the right answer.  When the template is evaluated (directly) by Mytype['mytype'], the locals $name and $title both have the value 'mytype', and there is another local, $param2.  When the template is evaluated by Mysubtype['/tmp/parsed1'], the locals $name and $title both have value '/tmp/parsed1', and there are additional locals $filepath and $source, but there is no local $param2.

Also, $param1 should not be part of either scope, contrary to the OP's remark that it is part of both.  The diff does not support the OP's claim, which I suspect is an incorrect inference.  If $param1 really is in both scopes, though, then that is inconsistent with Puppet's scoping documentation.

Finally, I observe that the templates are a bit of a red herring here.  They provide a convenient way to enumerate the contents of a scope, but the differences in the contents of scopes presented to them are not a question of templating.


John

jcbollinger

unread,
May 27, 2014, 10:44:04 AM5/27/14
to puppet...@googlegroups.com


On Tuesday, May 27, 2014 9:40:57 AM UTC-5, jcbollinger wrote:

[...] Puppet does not have nested scopes.


I confess that that's a bit of a simplification (see the docs I linked previously), but certainly the code presented does not create any scope nesting other than global / local.


John

Reply all
Reply to author
Forward
0 new messages