ripped out the guts of merge_config_hashes and put it in a merge_hashes utility sub
[catagits/Catalyst-Runtime.git] / lib / Catalyst / Utils.pm
index c3145d3..c6710b2 100644 (file)
@@ -6,6 +6,7 @@ use File::Spec;
 use HTTP::Request;
 use Path::Class;
 use URI;
+use Class::Inspector;
 
 =head1 NAME
 
@@ -19,9 +20,7 @@ See L<Catalyst>.
 
 =head1 METHODS
 
-=over 4
-
-=item appprefix($class)
+=head2 appprefix($class)
 
        MyApp::Foo becomes myapp_foo
 
@@ -34,7 +33,7 @@ sub appprefix {
     return $class;
 }
 
-=item class2appclass($class);
+=head2 class2appclass($class);
 
     MyApp::C::Foo::Bar becomes MyApp
     My::App::C::Foo::Bar becomes My::App
@@ -50,7 +49,7 @@ sub class2appclass {
     return $appname;
 }
 
-=item class2classprefix($class);
+=head2 class2classprefix($class);
 
     MyApp::C::Foo::Bar becomes MyApp::C
     My::App::C::Foo::Bar becomes My::App::C
@@ -66,7 +65,7 @@ sub class2classprefix {
     return $prefix;
 }
 
-=item class2classsuffix($class);
+=head2 class2classsuffix($class);
 
     MyApp::C::Foo::Bar becomes C::Foo::Bar
 
@@ -79,7 +78,7 @@ sub class2classsuffix {
     return $class;
 }
 
-=item class2env($class);
+=head2 class2env($class);
 
 Returns the environment name for class.
 
@@ -94,7 +93,7 @@ sub class2env {
     return uc($class);
 }
 
-=item class2prefix( $class, $case );
+=head2 class2prefix( $class, $case );
 
 Returns the uri prefix for a class. If case is false the prefix is converted to lowercase.
 
@@ -113,7 +112,7 @@ sub class2prefix {
     return $prefix;
 }
 
-=item class2tempdir( $class [, $create ] );
+=head2 class2tempdir( $class [, $create ] );
 
 Returns a tempdir for a class. If create is true it will try to create the path.
 
@@ -142,7 +141,7 @@ sub class2tempdir {
     return $tmpdir->stringify;
 }
 
-=item home($class)
+=head2 home($class)
 
 Returns home directory for given class.
 
@@ -175,7 +174,7 @@ sub home {
     return $home;
 }
 
-=item prefix($class, $name);
+=head2 prefix($class, $name);
 
 Returns a prefixed action.
 
@@ -190,7 +189,7 @@ sub prefix {
     return $name;
 }
 
-=item request($uri)
+=head2 request($uri)
 
 Returns an L<HTTP::Request> object for a uri.
 
@@ -199,7 +198,7 @@ Returns an L<HTTP::Request> object for a uri.
 sub request {
     my $request = shift;
     unless ( ref $request ) {
-        if ( $request =~ m/http/i ) {
+        if ( $request =~ m/^http/i ) {
             $request = URI->new($request)->canonical;
         }
         else {
@@ -212,11 +211,65 @@ sub request {
     return $request;
 }
 
-=back
+=head2 ensure_class_loaded($class_name)
+
+Loads the class unless it already has been loaded.
+
+=cut
+
+sub ensure_class_loaded {
+    my $class = shift;
+
+    return if Class::Inspector->loaded( $class ); # if a symbol entry exists we don't load again
+
+    # this hack is so we don't overwrite $@ if the load did not generate an error
+    my $error;
+    {
+        local $@;
+        eval "require $class";
+        $error = $@;
+    }
+
+    die $error if $error;
+    die "require $class was successful but the package is not defined"
+        unless Class::Inspector->loaded($class);
+
+    return 1;
+}
+
+=head2 merge_hashes($hashref, $hashref)
+
+Base code to recursively merge two hashes together with right-hand precedence.
+
+=cut
+
+sub merge_hashes {
+    my ( $lefthash, $righthash ) = @_;
+
+    return $lefthash unless defined $righthash;
+    
+    my %merged = %$lefthash;
+    for my $key ( keys %$righthash ) {\r
+        my $right_ref = ( ref $righthash->{ $key } || '' ) eq 'HASH';\r
+        my $left_ref  = ( ( exists $lefthash->{ $key } && ref $lefthash->{ $key } ) || '' ) eq 'HASH';\r
+        if( $right_ref and $left_ref ) {\r
+            $merged{ $key } = merge_hashes(
+                $lefthash->{ $key }, $righthash->{ $key }
+            );\r
+        }
+        else {
+            $merged{ $key } = $righthash->{ $key };
+        }\r
+    }
+    
+    return \%merged;
+}
+
 
 =head1 AUTHOR
 
 Sebastian Riedel, C<sri@cpan.org>
+Yuval Kogman, C<nothingmuch@woobling.org>
 
 =head1 COPYRIGHT