Am Mi 23. Feb 2011, 06:14:48, CFRANKS schrieb:
Show quoted text> and it output
> $VAR1 = {
> 'foo' => 'bar'
> };
> $VAR2 = $VAR1;
> Which shows that they both return a reference to the same data
structure.
right, because u don't use __PACKAGE__->config, yet.
Show quoted text> I don't recognize the problem you're describing
Short story:
The problem: I have 2 controllers, both are Controller::HTML::FormFu.
They need a different setup for the form parts:
My::Ctrl::form1:
FormFuStuff => {options}
My::Ctrl::form2:
FormFuStuff => { other options }
Actually FormFuStuff (_html_formfu_config) can only be set up via the
global "Controller::HTML::FormFu"-key.
$self->config returns the __PACKAGE__->config stuff
but nothing of the configfile!
(rule of thumb: ->config is ro at runtime)
So I just reread Catalyst and ::Component man page, just in case I see
ghosts...
Long story:
Almost feels like a little tutorial.
I'll attach a perl session. I hope it shows how these things can be
done a better way.
(This damn bug tracker doesn't allow some formatting ... does it? and
lacks a preview function)
regards,
Christoph Rudorff
========================================
In this expample I use every possibility to set some options.
I use the key "some_options" to demonstrate Catalyst config merging.
I think, a Controller Class like FormFu should use a single
key for all it's config so it doesn't pollute namespace.
So, it's just confusing (but ok), that actually this key is
"Controller::HTML::FormFu".
I want to set up {constructor}{config_file_path} for _my_ controller_s_
========================================
# myctrl.yml
#
name: MyCtrl
Controller::Root:
namespace: rooot
some_options:
from_config_files: I setup my ctrl here
path: finally, fetch files from here!
Controller::HTML::FormFu:
from_config_file: this goes nowhere ....
# this is the option I'd like to set per controller:
constructor:
config_file_path: set via cfile C:R
# by default, these options are not merged by Catalyst
# config system:
Controller::HTML::FormFu:
constructor:
config_file_path: set by cfile C:H:FF
some_options:
from_config_file_global: some global options for all FormFu
path: where to fetch the files???
========================================
# lib/MyCtrl/Controller/Root.pm
package MyCtrl::Controller::Root;
use Moose;
use namespace::autoclean;
# please fix the doc. use base is wrong.
BEGIN { extends 'Catalyst::Controller::HTML::FormFu' }
# set up factory defaults
__PACKAGE__->config(
namespace => 'whatever',
some_options => {
from_my_ctrl => 'factory defaults shall go here, no?',
path => 'factory defaults'
},
'Controller::HTML::FormFu' => {
from_my_ctrl => 'this actually goes to $self_config',
constructor => { config_file_path => 'set by factory defaults in C:R' },
}
);
sub index :Path :Args(0) {
my ( $self, $c ) = @_;
$DB::single=1;
# Hello World
$c->response->body( $c->welcome_message );
}
__PACKAGE__->meta->make_immutable;
1;
========================================
# let's drop a breakpoint and set some factoy defaults
# in the base class for this demonstration:
#
# lib/perl5/Catalyst/Controller/HTML/FormFu.pm
package Catalyst::Controller::HTML::FormFu;
...
__PACKAGE__->config(
some_options => {
from_fu_ctrl => 'the needful things',
path => 'put the files there',
},
constructor => {
config_file_path => 'set by factory defaults in C:H:FF'
},
);
...
after BUILD => sub {
my ( $self ) = @_;
my $app = $self->_app;
my $self_config = $self->config->{'Controller::HTML::FormFu'} || {};
my $parent_config = $app->config->{'Controller::HTML::FormFu'} || {};
my %defaults = ( ... );
my %args = ( %defaults, %$parent_config, %$self_config );
$DB::single=1;
========================================
Let's run debugger:
perl -d ./script/myctrl_test.pl /
...
DB<1> c
Catalyst::Controller::HTML::FormFu::CODE(0x3eec590)(.../webapps/perl.cpan/lib/perl5/Catalyst/Controller/HTML/FormFu.pm:85):
85: my %args = ( %defaults, %$parent_config, %$self_config );
DB<1> n
87: my $local_path = $app->path_to( 'root', 'formfu' );
DB<1> v
84: $DB::single=1;
85: my %args = ( %defaults, %$parent_config, %$self_config );
86
87==> my $local_path = $app->path_to( 'root', 'formfu' );
88
89: if ( !exists $args{constructor}{tt_args}
90 || !exists $args{constructor}{tt_args}{INCLUDE_PATH} && -d $local_path )
91 {
92: $args{constructor}{tt_args}{INCLUDE_PATH} = [$local_path];
93 }
#ok, lets see what we've got:
DB<1> x \%args
(just the importent bits)
0 HASH(0x4497498)
'constructor' => HASH(0x3eebac8)
'config_file_path' => 'set by factory defaults in C:R'
# ^^^^^ wrong ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
'from_my_ctrl' => 'this actually goes to $self_config'
'some_options' => HASH(0x3aa1e50)
'from_config_file_global' => 'some global options for all FormFu'
'path' => 'where to fetch the files???'
DB<2> x $parent_config
0 HASH(0x3a25af0)
'constructor' => HASH(0x3a88ef8)
'config_file_path' => 'set by cfile C:H:FF'
'some_options' => HASH(0x3aa1e50)
'from_config_file_global' => 'some global options for all FormFu'
'path' => 'where to fetch the files???'
DB<3> x $self_config
0 HASH(0x44bdee0)
'constructor' => HASH(0x3eebac8)
'config_file_path' => 'set by factory defaults in C:R'
'from_my_ctrl' => 'this actually goes to $self_config'
My opinions about that:
1. Catalyst::Component says, the place to do magic to the config is COMPONENT().
So what's the reason to use BUILD()? (Just wondering)
2. the %defaults should go to __PACKAGE__->config , factory defaults.
(e.g. look the {some_options}{from_fu_ctrl} below)
3. The only extra you want to do is to merge global options with the key:
"Controller::HTML::FormFu"
(and of course setup stuff like $regex_builder ...)
4. line 84 %args = ... only merges the first hash keys.
Better use Catalyst::Utils::merge_hashes for a deep merge
Actually everything is already done. Here are the lost options:
DB<4> x $self
0 MyCtrl::Controller::Root=HASH(0x3a629c8)
'Controller::HTML::FormFu' => HASH(0x3ef5ed0)
'constructor' => HASH(0x44cb338)
'config_file_path' => 'set via cfile C:R'
'from_config_file' => 'this goes nowhere ....'
'from_my_ctrl' => 'this actually goes to $self_config'
'_application' => 'MyCtrl'
'action_namespace' => 'rooot'
'actions' => HASH(0x44bd688)
empty hash
'catalyst_component_name' => 'MyCtrl::Controller::Root'
'constructor' => HASH(0x4497768)
'config_file_path' => 'set by factory defaults in C:H:FF'
'namespace' => 'rooot'
'some_options' => HASH(0x3ef83c0)
'from_config_files' => 'I setup my ctrl here'
'from_fu_ctrl' => 'the needful things'
'from_my_ctrl' => 'factory defaults shall go here, no?'
'path' => 'finally, fetch files from here!
# we also get the full merged config as arg[1] :
DB<21> x $_[1]
0 HASH(0x3dfdb18)
'Controller::HTML::FormFu' => HASH(0x3ef5ed0)
'constructor' => HASH(0x44cb338)
'config_file_path' => 'set via cfile C:R'
'from_config_file' => 'this goes nowhere ....'
'from_my_ctrl' => 'this actually goes to $self_config'
'_application' => 'MyCtrl'
'catalyst_component_name' => 'MyCtrl::Controller::Root'
'constructor' => HASH(0x4497768)
'config_file_path' => 'set by factory defaults in C:H:FF'
'namespace' => 'rooot'
'some_options' => HASH(0x3ef83c0)
'from_config_files' => 'I setup my ctrl here'
'from_fu_ctrl' => 'the needful things'
'from_my_ctrl' => 'factory defaults shall go here, no?'
'path' => 'finally, fetch files from here!'
# this is merged __PACKAGE__->config only :
DB<5> x $self->config
0 HASH(0x44bdb98)
'Controller::HTML::FormFu' => HASH(0x44bdee0)
'constructor' => HASH(0x3eebac8)
'config_file_path' => 'set by factory defaults in C:R'
'from_my_ctrl' => 'this actually goes to $self_config'
'constructor' => HASH(0x4497768)
'config_file_path' => 'set by factory defaults in C:H:FF'
'namespace' => 'whatever'
'some_options' => HASH(0x3cbf748)
'from_fu_ctrl' => 'the needful things'
'from_my_ctrl' => 'factory defaults shall go here, no?'
'path' => 'factory defaults'
# and this is config file only:
DB<6> x $app->config
0 HASH(0x2b244b8)
'Controller::HTML::FormFu' => HASH(0x3a25af0)
'constructor' => HASH(0x3a88ef8)
'config_file_path' => 'set by cfile C:H:FF'
'some_options' => HASH(0x3aa1e50)
'from_config_file_global' => 'some global options for all FormFu'
'path' => 'where to fetch the files???'
'Controller::Root' => HASH(0x3ab73c0)
'Controller::HTML::FormFu' => HASH(0x3aa2150)
'constructor' => HASH(0x3cedb78)
'config_file_path' => 'set via cfile C:R'
'from_config_file' => 'this goes nowhere ....'
'catalyst_component_name' => 'MyCtrl::Controller::Root'
'namespace' => 'rooot'
'some_options' => HASH(0x3ab7b10)
'from_config_files' => 'I setup my ctrl here'
'path' => 'finally, fetch files from here!'
'Plugin::ConfigLoader' => HASH(0x3408f00)
empty hash
'disable_component_resolution_regex_fallback' => 1
'home' => '/home/www/uconcert.web/webapps/fbug.test/MyCtrl'
'name' => 'MyCtrl'
'root' => Path::Class::Dir=HASH(0x32a2e98)
'file_spec_class' => undef
'volume' => ''
# merging global settings "Controller::HTML::FormFu" from configfile
should look like this:
use Catalyst::Utils;
$self->{'Controller::HTML::FormFu'} =
# or $self->{_html_formfu_config} =
Catalyst::Utils::merge_hashes(
$app->config->{'Controller::HTML::FormFu'}
$self->{'Controller::HTML::FormFu'}
)
result:
0 HASH(0x4587d78)
'constructor' => HASH(0x44b3128)
'config_file_path' => 'set via cfile C:R'
# right ^^^^^^^^^^^^^^^^^
'from_config_file' => 'this goes nowhere ....'
'from_my_ctrl' => 'this actually goes to $self_config'
'some_options' => HASH(0x3aa1e50)
'from_config_file_global' => 'some global options for all FormFu'
'path' => 'where to fetch the files???'