The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
Changes 06
META.json 33
META.yml 33
Makefile.PL 610
lib/RPC/ExtDirect/API/Method.pm 06
lib/RPC/ExtDirect/API.pod 49
lib/RPC/ExtDirect/Config.pod 69
lib/RPC/ExtDirect/Event.pod 65
lib/RPC/ExtDirect/Intro.pod 2545
lib/RPC/ExtDirect/Util.pm 32
lib/RPC/ExtDirect.pm 11
t/002_attr_parser.t 51
t/068_method.t 127
13 files changed (This is a version diff) 63127
@@ -1,3 +1,9 @@
+3.03  Thu Jan 29 22:58:24 PST 2015
+    - Fixed outdated attribute parser check that required at least one
+      name in params arrayref for named Methods
+    - Named Methods with empty params will force !strict in constructor
+    - Misc documentation fixes
+
 3.02  Mon Oct 27 17:36:12 PDT 2014
     - Added timeout and max_retries API config options
     - Some test fixes and improvements
@@ -41,11 +41,11 @@
    "release_status" : "stable",
    "resources" : {
       "bugtracker" : {
-         "web" : "http://github.com/nohuhu/RPC-ExtDirect/issues"
+         "web" : "https://github.com/nohuhu/RPC-ExtDirect/issues"
       },
       "repository" : {
-         "url" : "http://github.com/nohuhu/RPC-ExtDirect"
+         "url" : "https://github.com/nohuhu/RPC-ExtDirect"
       }
    },
-   "version" : "3.02"
+   "version" : "3.03"
 }
@@ -22,6 +22,6 @@ requires:
   JSON: 2.0
   perl: 5.006
 resources:
-  bugtracker: http://github.com/nohuhu/RPC-ExtDirect/issues
-  repository: http://github.com/nohuhu/RPC-ExtDirect
-version: 3.02
+  bugtracker: https://github.com/nohuhu/RPC-ExtDirect/issues
+  repository: https://github.com/nohuhu/RPC-ExtDirect
+version: 3.03
@@ -1,6 +1,9 @@
 use 5.006000;
 use ExtUtils::MakeMaker;
 
+use strict;
+use warnings;
+
 # Add the `devtest` target to run regression and POD tests in one go
 sub MY::postamble {
     return <<'END';
@@ -21,12 +24,13 @@ disttest : distdir
 END
 }
 
-my $MMVersion = $ExtUtils::MakeMaker::VERSION;
+my $MM_VERSION  = $ExtUtils::MakeMaker::VERSION;
+my $github_repo = 'https://github.com/nohuhu/RPC-ExtDirect';
 
 WriteMakefile(
     NAME              => 'RPC::ExtDirect',
     VERSION_FROM      => 'lib/RPC/ExtDirect.pm',
-    ($MMVersion >= 6.55
+    ($MM_VERSION >= 6.55
         ? ( BUILD_REQUIRES => {
                 'Test::More'            => '0.82',
             },
@@ -47,16 +51,16 @@ WriteMakefile(
     AUTHOR   => 'Alex Tokarev <tokarev@cpan.org>',
     LICENSE  => 'perl',
 
-    ($MMVersion >= 6.48
+    ($MM_VERSION >= 6.48
         ? ( MIN_PERL_VERSION => 5.006000, )
         : (),
     ),
 
-    ($MMVersion >= 6.46
+    ($MM_VERSION >= 6.46
         ? ( META_MERGE => {
             resources   => {
-                bugtracker  => 'http://github.com/nohuhu/RPC-ExtDirect/issues',
-                repository  => 'http://github.com/nohuhu/RPC-ExtDirect',
+                bugtracker  => "$github_repo/issues",
+                repository  => $github_repo,
             },
            },
         )
@@ -41,6 +41,12 @@ sub new {
                   :                'default'
                   ;
     
+    # If the Method is named, and params array is empty, force !strict
+    if ( $is_named ) {
+        $arg{params} = $arg{params} || []; # Better safe than sorry
+        $arg{strict} = !1 if !@{ $arg{params} };
+    }
+    
     # We avoid hard binding on the hook class
     eval "require $hook_class";
     
@@ -131,6 +131,11 @@ declared for this method, an exception will be thrown as well, unless
 strict argument checking is turned off
 (L<see below|/"Lazy parameter checking">).
 
+It is also possible to declare a named Method with I<no> mandatory
+parameters at all; do that by setting L</params> option to an empty
+arrayref: C<[]>. In that case, the calling convention is still honored
+but all parameters are treated as optional and no checks are performed.
+
 =head2 Lazy parameter checking
 
 Starting with Ext JS 4.2.2 and RPC::ExtDirect 3.0+, it is possible to
@@ -640,8 +645,8 @@ used.
 =item C<get_method_by_name>
 
 Instance method. Return the L<Method|RPC::ExtDirect::Intro/Method> object
-for the corresponding Action and Method name. Accepts two ordered
-arguments:
+for the corresponding Action and Method name, or C<undef>. Accepts two
+ordered arguments:
 
 =over 8
 
@@ -707,8 +712,8 @@ This parameter is mandatory.
 
 =item C<get_hook>
 
-Instance method. Returns the Hook object for a given criteria. Accepts
-named arguments in a hash.
+Instance method. Returns the Hook object for given criteria, or C<undef>.
+Accepts named arguments in a hash.
 
 When looking up Method level hook, C<action> or C<package> parameter is
 mandatory, as well as the C<method> name and hook C<type>. For Action
@@ -111,8 +111,8 @@ Default: C<'RPC::ExtDirect::API::Hook'>.
 
 When set to truthy value, API L<Action|RPC::ExtDirect::Intro/Action> names
 will default to package name with C<'::'> replaced with dots:
-C<'Foo::Bar::Baz' -> 'Foo.Bar.Baz'>, instead of using only the last chunk
-of the package name: C<'Foo::Bar::Baz' -> 'Baz'>.
+C<< 'Foo::Bar::Baz' -> 'Foo.Bar.Baz' >>, instead of using only the last
+chunk of the package name: C<< 'Foo::Bar::Baz' -> 'Baz' >>.
 
 Default: C<!1> (false).
 
@@ -328,7 +328,7 @@ Default: C<'RPC::ExtDirect::EventProvider'>.
 =item verbose_exceptions
 
 Turn informative exceptions on/off. For whatever reason, Ext.Direct spec
-requires server stack to return detailed exceptions in debugging mode,
+requires server stack to return detailed exceptions in debugging mode only,
 replacing them with generic "An error has occured" in production mode.
 Most probably this was done to increase application security, but as the
 result it hinders development and support greatly.
@@ -387,7 +387,7 @@ Default: C<'Ext.app.POLLING_API'>.
 =item namespace
 
 JavaScript namespace to be declared in the remoting API. See
-L<Ext.direct.RemotingProvider|http://docs-origin.sencha.com/extjs/5.0.0/apidocs/#!/api/Ext.direct.RemotingProvider-cfg-namespace>
+L<Ext.direct.RemotingProvider|http://docs.sencha.com/extjs/5.1/5.1.0-apidocs/#!/api/Ext.direct.RemotingProvider>
 documentation for more detailed information on this option.
 
 Default: C<''> (empty string).
@@ -399,6 +399,9 @@ to automatically set up RemotingProvider and PollingProvider on the
 client side to the Ext.Direct declaration JavaScript chunk, so that
 JavaScript application won't need to do that.
 
+This option is deprecated as of RPC::ExtDirect 3.0, and should not
+be used going forward.
+
 Default: C<!1> (false).
 
 =item no_polling
@@ -412,14 +415,14 @@ Default: C<!1> (false).
 =item max_retries
 
 Number of times for the client side to re-attempt delivery on failure
-of a call. (see Ext.direct.RemotingProvider.maxRetries).
+of a call. (see L<Ext.direct.RemotingProvider.maxRetries|http://docs.sencha.com/extjs/5.1/5.1.0-apidocs/#!/api/Ext.direct.RemotingProvider-cfg-maxRetries>).
 
 Default: C<undef>.
 
 =item timeout
 
 The timeout for the client side to use for each request
-(see Ext.direct.RemotingProvider.timeout).
+(see L<Ext.direct.RemotingProvider.timeout|http://docs.sencha.com/extjs/5.1/5.1.0-apidocs/#!/api/Ext.direct.RemotingProvider-cfg-timeout>).
 
 Default: C<undef>.
 
@@ -44,11 +44,10 @@ to serialize a self-contained object. To avoid this, set a global Config
 option L<json_options|RPC::ExtDirect::Config/json_options> to include
 C<allow_blessed> flag:
 
-    my $config = RPC::ExtDirect::Config->new(
-        json_options => {
-            allow_blessed => 1,
-        },
-    );
+    my $config = RPC::ExtDirect->get_api->config;
+    $config->json_options({
+        allow_blessed => 1,
+    });
 
 =head1 METHODS
 
@@ -80,7 +79,7 @@ typing compatibility with Exception and Request objects.
 
 =item C<result>
 
-Instance method. Returns an Event hashref in format supported by
+Instance method. Returns an Event hashref in format required by
 Ext.Direct client stack. Not intended to be called directly.
 
 =back
@@ -65,19 +65,19 @@ however the particular details can differ significantly.
 
 To deal with the web server differences, RPC::ExtDirect adopted the
 core-periphery architecture. Transport layer core, provided by the
-L<RPC::ExtDirect> CPAN distribution, is complemented by a peripheral
-distribution called a I<gateway> that works with a particular web
-server environment. The gateway is responsible for implementing the
+L<RPC::ExtDirect> CPAN distribution, is complemented by peripheral
+distributions called I<gateways> that work with particular web
+server environments. The gateway is responsible for implementing the
 features missing in a web server interface, if any.
 
 Since the gateway modules implement the "lowest common denominator"
 abstraction layer, it is fairly easy to use an Ext.Direct application
 with several different gateways at the same time. The most common use
-for this is testing; the added benefit is that the application becomes
-independent of the web server environment and can be ported easily if
-such a need arises.
+case for this is unit testing; the added benefit is that the application
+becomes independent of the web server environment and can be ported
+easily if such a need arises.
 
-See L<RPC::ExtDirect/GATEWAYS> for a list of available gateways.
+See L<RPC::ExtDirect/GATEWAYS> for the list of available gateways.
 
 =head1 TERMINOLOGY
 
@@ -93,9 +93,9 @@ of L<remoting|/"Remoting API"> and L<polling|/"Polling API"> parts.
 =item API declaration
 
 JavaScript chunk that encodes L</API>. Usually generated
-by application server and retrieved by client once upon startup.
-Another option is to embed API declaration in client side application
-code.
+by application server and retrieved by client once upon startup;
+another popular option is to embed API declaration in client side
+application code at the build time (using Sencha Cmd).
 
 API declaration is generated by L<RPC::ExtDirect::API> module.
 
@@ -103,12 +103,13 @@ API declaration is generated by L<RPC::ExtDirect::API> module.
 
 The main part of the L</"API declaration">, it declares the L<Actions|/Action>
 and L<Methods|/Method> available to the client, as well as their calling
-patterns, and other parameters.
+conventions, and other parameters.
 
 =item Polling API
 
 Used to declare the existence of L<Event Providers|/"Event Provider"> and
-their credentials, basically the URI to use.
+their credentials, basically the URI to use when polling for
+L<Events|/Event>.
 
 =item Router
 
@@ -139,8 +140,8 @@ signature conforming to Method's declaration in the L</API>.
 
 =item Ordered Method
 
-A L</Method> that accepts zero or more parameters in ordered fashion, or by
-position (in a list). See more in
+A L</Method> that accepts zero or more parameters in ordered fashion, i.e.
+by position (in a list). See more in
 L<RPC::ExtDirect/"METHODS AND CALLING CONVENTIONS">.
 
 =item Named Method
@@ -151,8 +152,8 @@ L<RPC::ExtDirect/"METHODS AND CALLING CONVENTIONS">.
 =item Form Handler Method
 
 A L</Method> that accepts form submits. All form field values are passed to
-the Form handler in a hash, C<field => value>. The only practical reason to
-use Form handlers is to process file uploads; see
+the Form handler in a hash, C<< field => value >>. The only practical reason
+to use Form handlers is to process file uploads; see
 L<FILE UPLOADS|RPC::ExtDirect/"FILE UPLOADS"> for more information. See also
 L<RPC::ExtDirect/"METHODS AND CALLING CONVENTIONS"> for more information on
 Form handlers calling convention.
@@ -181,7 +182,7 @@ only for catastrophic conditions. Nearest analog is status code 500
 for HTTP responses.
 
 Examples of Exceptions are: request JSON is broken and can't be decoded;
-called Method dies because of internall error; Result cannot be encoded
+called Method dies because of internal error; Result cannot be encoded
 in JSON, etc.
 
 =item Event
@@ -189,7 +190,7 @@ in JSON, etc.
 An asynchronous notification that can be generated by server side and
 passed to client side, resulting in some reaction. Events are useful
 for status updates, progress indicators and other predictably occuring
-conditions and events.
+conditions.
 
 =item Event Provider
 
@@ -243,14 +244,14 @@ over time. The only way to ensure that your server side API keeps
 working exactly as the client side expects it to is via continuous
 testing.
 
-However, testing a server side API with the actual JavaScript code
+However testing a server side API with the actual JavaScript code
 that will consume the API is a daunting task. You would need an
 instance of the Web server you are going to use in production, a
 headless Web browser, a ton of infrastructure to keep all this up
 to date; not even mentioning the time spent maintaining the whole
 setup. If this picture makes you cringe with frustration, that's
 totally understandable. But fear not, RPC::ExtDirect has a truly
-Perlish answer to this question (making hard things possible).
+Perlish answer to this problem (making hard things possible).
 
 L<Test::ExtDirect> is the recommended way to unit test your Ext.Direct
 code. To be precise, it is hardly right to call it unit testing when
@@ -279,7 +280,7 @@ for the C<add> subroutine created above looks in practice:
     
     is $result, 4, "addition result matches";
 
-Now, how hard is that?!
+Now how hard is that?!
 
 =head1 GOING FURTHER
 
@@ -318,6 +319,18 @@ turn off strict checking:
         ...
     }
 
+It is always a good idea to declare at least some mandatory parameters;
+however if you want all named arguments to be passed to your Method with
+no checking, use empty params array:
+
+    sub named_no_checks : ExtDirect(params => []) {
+        my ($class, %arg) = @_;
+        
+        my $foo = $arg{foo};
+        my $bar = $arg{bar};
+        ... # etc
+    }
+
 =head2 Form submits
 
 An Ext.Direct Method can be used to accept form submits in
@@ -335,6 +348,8 @@ non-HTML5 browsers (think IE9 and below):
         }
     }
 
+See more in L<RPC::ExtDirect/"FILE UPLOADS">.
+
 =head2 Handling errors
 
 When your server side code encounters an irrecoverable error, it is
@@ -352,8 +367,9 @@ but having two sets of logic would be unwieldy; RPC::ExtDirect compromises
 by sending generic exceptions "An error has occured" in production mode
 (default).
 
-To turn on global debugging, set the L<debug option|RPC::ExtDirect::Config/debug>
-in the L<global API instance's|RPC::ExtDirect::API/"GLOBAL API TREE INSTANCE">
+To turn on global debugging, set the
+L<debug option|RPC::ExtDirect::Config/debug> in the
+L<global API instance's|RPC::ExtDirect::API/"GLOBAL API TREE INSTANCE">
 Config:
 
     # Place this in the main app server code
@@ -362,7 +378,7 @@ Config:
     RPC::ExtDirect->get_api->config->debug(1);
 
 If you are comfortable with exposing internal details of your app server to
-the outside world even in production mode, turn on
+the outside world even in production mode (and you shouldn't be!), turn on
 L<verbose_exceptions|RPC::ExtDirect::Config/verbose_exceptions>:
 
     # This goes to the main app server, too
@@ -370,6 +386,9 @@ L<verbose_exceptions|RPC::ExtDirect::Config/verbose_exceptions>:
     
     RPC::ExtDirect->get_api->config->verbose_exceptions(1);
 
+Be aware that it is an B<extremely> bad idea because it can help malicious
+parties to find an attack vector to your application!
+
 =head2 Using environment objects
 
 Suppose that you want to restrict some parts of the API to be accessible
@@ -458,7 +477,7 @@ logging:
 
 Set this way, C<log_everything> will be called after every Ext.Direct
 Method invocation, even if a C<before> hook canceled it. See
-L<RPC::ExtDirect::API::Hook> for the gory detail.
+L<RPC::ExtDirect::API::Hook> for the gory details.
 
 =head1 SEE ALSO
 
@@ -466,3 +485,4 @@ Live code examples are provided with L<CGI::ExtDirect> module in the
 C<examples> directory.
 
 =cut
+
@@ -220,9 +220,8 @@ sub parse_attribute {
             my $arg_names = shift @$data;
 
             croak "ExtDirect attribute 'params' must be followed by ".
-                  "arrayref containing at least one parameter name ".
-                  "at $file line $line"
-                if ref $arg_names ne 'ARRAY' || @$arg_names < 1;
+                  "arrayref at $file line $line"
+                if ref $arg_names ne 'ARRAY';
 
             # Copy the names
             $attr{params} = [ @{ $arg_names } ];
@@ -17,7 +17,7 @@ use RPC::ExtDirect::Util;
 # at the end.
 #
 
-our $VERSION = '3.02';
+our $VERSION = '3.03';
 
 ### PACKAGE GLOBAL VARIABLE ###
 #
@@ -1,7 +1,7 @@
 use strict;
 use warnings;
 
-use Test::More tests => 75;
+use Test::More tests => 74;
 
 use RPC::ExtDirect::Test::Util;
 use RPC::ExtDirect::Util;
@@ -107,10 +107,6 @@ __DATA__
     input => [ params => {} ],
     xcpt  => qr{attribute 'params' must be followed},
 }, {
-    name  => 'params empty arrayref',
-    input => [ params => [] ],
-    xcpt  => qr{attribute 'params' must be followed},
-}, {
     name  => 'formHandler',
     input => ['formHandler'],
     want  => { formHandler => 1, },
@@ -3,7 +3,7 @@
 use strict;
 use warnings;
 
-use Test::More tests => 59;
+use Test::More tests => 63;
 
 use RPC::ExtDirect::Test::Util;
 use RPC::ExtDirect::Config;
@@ -405,6 +405,32 @@ __DATA__
         output => [1, 'env', 2],
     },
     {
+        name => 'Named empty params strict no env',
+        type => 'prepare',
+        method => {
+            params => [],
+        },
+        input => {
+            env => 'env',
+            input => { foo => 1, bar => 2, },
+        },
+        out_type => 'hash',
+        output => { foo => 1, bar => 2, },
+    },
+    {
+        name => 'Named empty params !strict no env',
+        type => 'prepare',
+        method => {
+            params => [], strict => !1,
+        },
+        input => {
+            env => 'env',
+            input => { foo => 1, bar => 2, },
+        },
+        out_type => 'hash',
+        output => { foo => 1, bar => 2, },
+    },
+    {
         name => 'Named strict no env',
         type => 'prepare',
         method => {