Title: Pseudo Lexical State Parameters

I noticed at:
  http://poe.perl.org/?POE_RFCs/Lexical_state_parameters

That there was a desire to: "Turn @_[KERNEL, HEAP, etc.] into regular variables, somehow"

Attached and also inlined at the bottom, you'll find a first attempt patch against Session.pm. If you like, I can easily whip up a similar patch for NFA.pm

What it does, is to push an anonymous array of parameters onto a stack before invoking a state, and then pop if off afterwards. There are a complimentary set of subroutine declarations which are pushed out via "import" which allow you to access the parameters at the top of the stack as so:

$_[OBJECT]      ->  object()
$_[SESSION]     ->  session()
$_[KERNEL]      ->  kernel()
$_[HEAP]        ->  heap()
$_[STATE]       ->  state()
$_[SENDER]      ->  sender()
$_[CALLER_FILE] ->  caller_file()
$_[CALLER_LINE] ->  caller_line()
@_[ARG0..$#_]   ->  args()

I continue to pass all the test I previously passed on Win32 after the application of this test.

enjoy.


--- Session.pm  Sun Oct 20 16:55:20 2002
+++ Session.cgg Mon Nov 11 17:30:07 2002
@@ -118,8 +118,12 @@
 sub ARG8    () { 17 }
 sub ARG9    () { 18 }
 
+my @params;
 sub import {
-  my $package = caller();
+  my $package;
+  for ( my $i=0; $package = [caller($i)]->[0]; $i++ ) {
+    last unless $package->isa('POE::Session')
+  }
   no strict 'refs';
   *{ $package . '::OBJECT'  } = \&OBJECT;
   *{ $package . '::SESSION' } = \&SESSION;
@@ -139,6 +143,16 @@
   *{ $package . '::ARG9'    } = \&ARG9;
   *{ $package . '::CALLER_FILE' } = \&CALLER_FILE;
   *{ $package . '::CALLER_LINE' } = \&CALLER_LINE;
+
+  *{ $package . '::object'      } = sub { $params[-1]->[OBJECT] };
+  *{ $package . '::session'     } = sub { $params[-1]->[SESSION] };
+  *{ $package . '::kernel'      } = sub { $params[-1]->[KERNEL] };
+  *{ $package . '::heap'        } = sub { $params[-1]->[HEAP] };
+  *{ $package . '::state'       } = sub { $params[-1]->[STATE] };
+  *{ $package . '::sender'      } = sub { $params[-1]->[SENDER] };
+  *{ $package . '::caller_file' } = sub { $params[-1]->[CALLER_FILE] };
+  *{ $package . '::caller_line' } = sub { $params[-1]->[CALLER_LINE] };
+  *{ $package . '::args' }        = sub { @{$params[-1]}[ARG1..$#params] };
 }
 
 #------------------------------------------------------------------------------
@@ -595,41 +609,37 @@
     $state = EN_DEFAULT;
   }
 
-  # If we get this far, then the state can be invoked.  So invoke it
-  # already!
-
-  # Inline states are invoked this way.
+  # If we get this far, then the state can be invoked.  Setup context
+  # so parameter shortcuts may be used, and invoke it. (Per Kernel.pm
+  # scalar return values are assumed)
+
+  my $return;
+  push @params, [
+    undef,                          # object
+    $self,                          # session
+    $POE::Kernel::poe_kernel,       # kernel
+    $self->[SE_NAMESPACE],          # heap
+    $state,                         # state
+    $source_session,                # sender
+    undef,                          # unused #6
+    $file,                          # caller file name
+    $line,                          # caller file line
+    @$etc                           # args
+  ];
 
   if (ref($self->[SE_STATES]->{$state}) eq 'CODE') {
-    return $self->[SE_STATES]->{$state}->
-      ( undef,                          # object
-        $self,                          # session
-        $POE::Kernel::poe_kernel,       # kernel
-        $self->[SE_NAMESPACE],          # heap
-        $state,                         # state
-        $source_session,                # sender
-        undef,                          # unused #6
-        $file,                          # caller file name
-        $line,                          # caller file line
-        @$etc                           # args
-      );
-  }
-
-  # Package and object states are invoked this way.
-
-  my ($object, $method) = @{$self->[SE_STATES]->{$state}};
-  return
-    $object->$method                    # package/object (implied)
-      ( $self,                          # session
-        $POE::Kernel::poe_kernel,       # kernel
-        $self->[SE_NAMESPACE],          # heap
-        $state,                         # state
-        $source_session,                # sender
-        undef,                          # unused #6
-        $file,                          # caller file name
-        $line,                          # caller file line
-        @$etc                           # args
-      );
+    # Inline states are invoked this way.
+    $return = $self->[SE_STATES]->{$state}->(@{$params[-1]});
+  }
+  else {
+    # Package and object states are invoked this way.
+    my ($object, $method) = @{$self->[SE_STATES]->{$state}};
+    $params[-1]->[OBJECT] = $object;
+    $return = $object->$method(@{$params[-1]}[1..$#{$params[-1]}])
+  }
+
+  pop @params;
+  $return;
 }
 
 #------------------------------------------------------------------------------

--
Garrett Goebel
IS Development Specialist

ScriptPro                   Direct: 913.403.5261
5828 Reeds Road               Main: 913.384.1008
Mission, KS 66202              Fax: 913.384.2180
www.scriptpro.com          [EMAIL PROTECTED]

 

Attachment: S.patch
Description: Binary data

Reply via email to