As far as I know "inner classes" are an anti pattern(for the lack of a better term)
Each class should live in its own file.
More than one class per file is discouraged
--
You received this message because you are subscribed to the Google Groups "Puppet Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to puppet-users...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/puppet-users/5418CF25.8070101%40gmail.com.
For more options, visit https://groups.google.com/d/optout.
Le 17/09/2014 04:26, Sebastian Otaegui a écrit :
> As far as I know "inner classes" are an anti pattern(for the lack of a
> better term)
>
> Each class should live in its own file.
>
> More than one class per file is discouraged
I agree. It's better to define "inner classes" in separate files
(my_module::internal1 in my_module/internal1.pp, my_module::internal2
in my_module/internal2.pp etc).
But this is not really my question. My question is: which pattern should
I use:
a) to define inner classes (indeed in a specific file)
b) and to call inner classes in the "my_module" class (which is the
"top level" class called by the user of my_module)
knowing that a inner class needs to use variables defined in
my_module::params, but among these variables, maybe severals
variables are parameters of the my_module class with a different
value of the default value proposed in my_module::params.
This one?
class my_module::internal (
$var2,
$var3,
) {
require my_module::params
notify { "value of foo1 -> $my_module:params::foo1": }
notify { "value of foo2 -> $my_module:params::foo2": }
}
Or maybe another one...?
--
You received this message because you are subscribed to the Google Groups "Puppet Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to puppet-users...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/puppet-users/a76e0b14-9719-4d18-843c-6ecea3ec1e3e%40googlegroups.com.
In fact, It's curious. I have made some tests with puppet 3.7.0
on Debian Wheezy and I can simply do this:
class my_module::params {
## API of the module ##
$var1 = default_value1
$var2 = default_value2
## shared variables between the classes of my_module
## but they are not part of the API module
$foo1 = default_value_foo1
$foo2 = default_value_foo2
...
}
class my_module (
$var1 = $my_module::params::var1,
$var2 = $my_module::params::var2,
) inherits my_module::params {
include my_module
}
class my_module::internal {
file { '/tmp/test_internal.txt':
content => template('test/test_internal.txt.erb'),
}
notify { 'm1': message => "var1 = ${my_module::var1}", }
notify { 'm2': message => "var2 = ${my_module::var2}", }
notify { 'm3': message => "foo1 = ${my_module::foo1}", }
notify { 'm4': message => "foo2 = ${my_module::foo2}", }
}
It's curious because I use no inheritance in my_module::internal,
no require etc. and despite that I can access to the variables of
my_module. Is it normal?
One thing very curious too: in the my_module::internal class
I can access to $var1 with this syntax :
${my_module::var1}
and $var1 is empty. Ok, I think I understand that. But in my
template "test_internal.txt.erb" I can use directly:
blabla <%= @var1 %> blabla
without the fully qualified name. Here, I don't understand.
Anyway, although I do not understand well the "scope" mechanism
etc. I feel that I can just use this design for inner classes :
class my_module::internal {
# No inheritance, no require of my_module::params etc.
# It's unnecessary.
# In the class, I must use the fully qualified name
# to access to a variable of my_module inherited by
# my_module::params (and sometimes overwritten).
# For instance:
notify { 'm1': message => "var1 = ${my_module::var1}", }
# But in templates, I can directy use @var1.
}
Am I wrong?
Or, if I understand well, when I have:
class my_module {
include my_module::internal
}
I can say: "my_module::internal" inherits my_module. Is that correct?
> With that out of the way, it is better to say
> that the result you observe is among the valid possibilities than to say it
> is "normal".
>
> All class variables have global visibility regardless of inheritance or
> declaration (e.g. via include / require).
Do you mean that with:
class my_module {
include my_module::internal
}
In the body of my_module::internal class I can access to the variables
defined in my_module class? With a unqualified name?
> The main purpose of all that *as
> it pertains to variables* is to ensure that Puppet evaluates classes during
> catalog compilation in an order that assigns values to those variables
> before those values are used. It also serves a documentary purpose,
> showing clearly that one class has a dependency on another.
>
>
>
>> One thing very curious too: in the my_module::internal class
>> I can access to $var1 with this syntax :
>>
>> ${my_module::var1}
>>
>
>
> No, you can't. There is no $var1 in class my_module::internal, so you are
> not accessing such a variable. You are instead accessing
> $my_module::params::var1 via an alias (that alias resulting from class
> my_module inheriting my_module::params). Don't use that alias, even in
> class my_module.
Ok.
>> and $var1 is empty. Ok, I think I understand that. But in my
>> template "test_internal.txt.erb" I can use directly:
>>
>> blabla <%= @var1 %> blabla
>>
>> without the fully qualified name. Here, I don't understand.
>>
>
>
> I don't believe you.
I can give you a precise and quick (if you have already a Debian Wheezy)
process to reproduct this. I take a Debian Wheezy, updated and cleaned
(it's a simple VM in Virtualbox). And here is the process:
# And here is the result of my template.
root@wheezy-clean:/etc/puppet/environments# cat /tmp/internal.txt
# Class test::internal
var1 = specific_value_var1 <---------- Here!!!
var2 = default_value_var2
foo1 = value_foo1
foo2 = value_foo2
root@wheezy-clean:/etc/puppet/environments# cat /tmp/test.txt
# Class test
var1 = specific_value_var1
var2 = default_value_var2
foo1 = value_foo1
foo2 = value_foo2
-------------------------------------------------------------------
I have:
var1 = specific_value_var1
in the /tmp/internal.txt file but in my template internal.txt.erb
I use :
var1 = <%= @var1 %>
Did you have the same result? I don't understand and for me it's
not logical.
Another curious thing: even if I put:
$var1 = "internal"
in the test::internal class, the /tmp/test.txt don't change.
> That form of reference would work of class
> my_module::internal were inheriting my_module::params (or class my_module)
> because of the aliasing mechanism I described. It would also work if
> my_module::internal had a parameter or an ordinary variable of its own
> named "var1". It will not work with the code you actually presented.
I understand. But in this case, where is my error in the
commands above?
I will continue to think about your long answers (thank you again
for the help). For starters, I would like to known where I'm
wrong in the example above. Maybe I'm very tired and I missed something
simple and stupid.
class test::internal {
notify { 'iv1': message => "Internal var1 = $::test::var1", }
notify { 'iv2': message => "Internal var2 = $::test::var2", }
notify { 'if1': message => "Internal foo1 = $::test::foo1", }
notify { 'if2': message => "Internal foo2 = $::test::foo2", }
# So, in templates, I use the syntax scope['::test::var']
# (I'm using Puppet 3.7.1 so -> scope[...])
file { '/temp/internal.txt':
content => inline_template("var1=<%= scope['::test::var1'] %>\nfoo2=<%= scope['::test::foo2'] %>\n"),
}
}
-----------------------------------------------------
I use $::test::xxx in class::internal not $::test::params::xxx
because when xxx is "var1" or "var2", I want to have the value of
var1 and var2 given as parameters of the test class (I don't want
the default value of var1 and var2).
> No, not in the slightest. I mean that if class my_module::params has a
> local variable with unqualified name "foo1", then that variable can be
> referenced from any class in any module as $my_module::params::foo1,
> regardless of any inheritance or include / require / contain statements
> anywhere.
Hum... there is exception, isn't? For instance, it depends of the
order of the class in the catalog, I'm wrong?
For instance, with this manifest:
-----------------------------------------------------
include ::test1
include ::test2
class test1 {
$var1 = "var1"
notify { 'm1': message => "var2 = $::test2::var2", }
}
class test2 {
$var2 = "var2"
notify { 'm2': message => "var1 = $::test1::var1", }
}
-----------------------------------------------------
I have this result:
~$ puppet apply manifest.pp
Warning: Scope(Class[Test1]): Could not look up qualified variable '::test2::var2'; class ::test2 has not been evaluated
Notice: Compiled catalog for wheezy-clean.chezmoi.priv in environment production in 0.02 seconds
Notice: var1 = var1
Notice: /Stage[main]/Test2/Notify[m2]/message: defined 'message' as 'var1 = var1'
Notice: var2 =
Notice: /Stage[main]/Test1/Notify[m1]/message: defined 'message' as 'var2 = '
Notice: Finished catalog run in 0.41 seconds
And in this case, I don't understand. I thought that :
$var1 = "value_var1" # LINE A
include ::test::internal # LINE B
and
include ::test::internal # LINE B
$var1 = "value_var1" # LINE A
was completely equivalent. Am I wrong?