[Catalyst-commits] r14542 - trunk/examples/CatalystAdvent/root/2014

jnapiorkowski at dev.catalyst.perl.org jnapiorkowski at dev.catalyst.perl.org
Tue Dec 9 16:03:39 GMT 2014


Author: jnapiorkowski
Date: 2014-12-09 16:03:39 +0000 (Tue, 09 Dec 2014)
New Revision: 14542

Added:
   trunk/examples/CatalystAdvent/root/2014/7.pod
Log:
another article

Added: trunk/examples/CatalystAdvent/root/2014/7.pod
===================================================================
--- trunk/examples/CatalystAdvent/root/2014/7.pod	                        (rev 0)
+++ trunk/examples/CatalystAdvent/root/2014/7.pod	2014-12-09 16:03:39 UTC (rev 14542)
@@ -0,0 +1,269 @@
+=head1 How I got started contributing to Catalyst
+
+From Mailing list to first commit.
+
+=head1 April 28, 2006 - jjn1056
+
+There is some strange things going
+on when I have a config in a base controller.  For
+example I have a class "element" that inherits from
+"Catalyst::Controller" which has the following line
+(again this is contrived a bit for clarity):
+
+    package element;
+
+    use strict;
+    use warnings;
+
+    use base qw/Catalyst::Controller/;
+
+    __PACKAGE__->config( view => 'element');
+
+    sub view
+    {
+      $self = shift;
+      return $self->{view};
+    }
+
+Then I have two classes that inherit from this element
+class:
+
+    package page;
+
+    use base qw/element/;
+
+    __PACKAGE__->config( view => 'page');
+
+
+and
+
+    package portlet;
+
+    use base qw/element/;
+
+    __PACKAGE__->config( view => 'portlet');
+
+So all three classes have a method called "view". 
+However this method doesn't do what I would think it
+would.  If I subclass any of these three classes for a
+catalyst controller and call $self->view on that
+subclass I always get 'portlet' as a response, instead
+of what was defined in the config for the local class.
+Maybe I just don't understand how this is supposed to
+work?
+
+--john napiorkowski
+
+=head1 April 28, 2006 - mst
+
+Not sure, that looks pretty much fine. It may be something going a bit odd in 
+the way the Class::Data::Inheritable setup works, though I've never 
+encountered any major problems. Try doing
+
+__PACKAGE__->_config({ %{ __PACKAGE__->_config } });
+
+or so before you call ->config in the subclasses and see if it sorts it. If it 
+does, a failing test case against Catalyst (since that shouldn't be necessary) 
+would be welcome :)
+
+=head1 April 28, 2006 - jjn1056
+
+I spent a lot of time digging into the trouble with
+using __PACKAGE__->config with subclassed controllers.
+The short story is that the solution from Matt (using
+"__PACKAGE__->_config({ %{ __PACKAGE__->_config }
+});") did work, although it's not so pretty since you
+need to put it in front of EVERY controller that is
+subclassing.
+
+I thought I'd show my test case so that other people
+having this trouble might be helped.  I also hope I
+can find a more elegant solution eventually.
+
+Here's the example.
+
+Say you have a base controller like the following in
+/lib (but not under /Controller since this is just a
+base class to encapsulate some functionality):
+
+    package test_controller;
+
+    use strict;
+    use warnings;
+
+    use base 'Catalyst::Controller';
+
+    __PACKAGE__->config( anything    => 'any' );
+
+    return 1;
+
+and then you have two controllers that are under
+/Controllers and are actually registered actions that
+Catalyst can find:
+
+    package MyApp::Controller::test1;
+
+    use strict;
+    use warnings;
+    use Data::Dumper;
+
+    use base 'test_controller';
+
+    __PACKAGE__->config( key => 'value' );
+            
+    sub default : Private
+    {
+        my ($self, $c)    = @_;
+        
+        $c->response->body(Dumper($self));
+    }
+
+    return 1;
+
+    package MyApp::Controller::test2;
+
+    use strict;
+    use warnings;
+    use Data::Dumper;
+
+    use base 'test_controller';
+            
+    sub default : Private
+    {
+        my ($self, $c)    = @_;
+        
+        $c->response->body(Dumper($self));
+    }
+
+    return 1;
+
+Now, the controllers test1 and test2 should expect to
+inherit config data from the base test_controller, and
+as well test1 adds it's own config data.  So the
+output of each test1 and test2 would reflect that. 
+However that is not what happens.  test2 (and any
+other controllers that are alphanumerically ordered
+AFTER test1) inherit config from both the base
+test_controller class and from test1 controller.
+
+Here's the actually output of the above two
+controllers:
+
+[http://localhost/test1]
+
+    $VAR1 = bless( {
+                    'anything' => 'any',
+                    'key' => 'value'
+                  }, 'MyApp::Controller::test1' );
+
+[http://localhost/test2]
+
+    $VAR1 = bless( {
+                    'anything' => 'any',
+                    'key' => 'value'
+                  }, 'MyApp::Controller::test2' );
+
+As you can see /test2 is getting some stuff from the
+previous controller.  However if I made a /test0
+controller exactly like test1 this would not happen. 
+Only controllers that sort post the /test1 would be
+affected.
+
+Now the solution that was given was to add some
+"__PACKAGE__->_config({ %{ __PACKAGE__->_config } });"
+prior to the normal config call.  This has to be added
+to EVERY single controller that is inheriting from a
+base controller.
+
+For example:
+
+    package MyApp::Controller::test1;
+
+    use strict;
+    use warnings;
+    use Data::Dumper;
+
+    use base 'test_controller';
+
+    __PACKAGE__->_config({ %{ __PACKAGE__->_config } });
+    __PACKAGE__->config( key => 'value' );
+            
+    sub default : Private
+    {
+        my ($self, $c)    = @_;
+        
+        $c->response->body(Dumper($self));
+    }
+
+    return 1;
+
+    package MyApp::Controller::test2;
+
+    use strict;
+    use warnings;
+    use Data::Dumper;
+
+    use base 'test_controller';
+
+    __PACKAGE__->_config({ %{ __PACKAGE__->_config } });
+        
+    sub default : Private
+    {
+        my ($self, $c)    = @_;
+        
+        $c->response->body(Dumper($self));
+    }
+
+    return 1;
+
+And now everything will JUST WORK.  it works by
+resetting the private _config method (which takes hash
+ref) to whatever it's value is supposed to be.
+
+Although this solution does the trick, I looked into
+this further, since I really think this solution is a
+bit undesirable.  Personally I prefer to encapsulate
+common behavior to base classes (as I am sure many of
+you do) and having that line stuck in the top of every
+controller is just going to cause me trouble sooner or
+later.  For example I am sure that myself or another
+programming will forget to do this, or not understand
+why it is there in the first place and remove it.
+
+=head1 April 28, 2006 - mst
+
+Yes. That's why I was guiding you towards a test case we can commit to 
+Catalyst trunk and get this fixed in Catalyst::Component itself.
+
+I already grasped the trouble. That's how I was able to give you a workaround :)
+
+Can I have that test patch please?
+
+=head1 May 7, 2007
+
+L<https://github.com/perl-catalyst/catalyst-runtime/commit/5e7073968974a588522d61b3a72b23cd87a8121a>
+
+=head1 Conclusion
+
+Many of us get started contributing to opensource because we have a
+particular itch to scratch.  The main think is to make the effort.  You
+could either introduce a local hack into your project source code (and
+forever curse yourself and your replacements with supporting it).  Or
+you could try to find a way to fix it once and for all time.
+
+When I went to the mailing with my issue I'd only been using Catalyst for
+a handful of months.  I was in no way an expert on the codebase and I was
+very new to open source contributing.  So you don't need to be a kung fu
+master to help out!
+
+You might not be able to fix the problem you find, but it you make the
+effort to learn to test suite well enough to present us with a cogent
+test case demonstrating your problem I can assure you that effort to
+fix it would be made.  And hopefully the fact you learned to actually make
+a test case commit will make it easier for you down the road.
+
+=head1 Author
+
+John Napiorkowski L<jjnapiork at cpan.org|email:jjnapiork at cpan.org>
+
+=cut




More information about the Catalyst-commits mailing list