Stories
Slash Boxes
Comments
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

jsmith (3335)

jsmith
  (email not shown publicly)
http://www.jamesgottlieb.com/
Jabber: jgsmith@tamu.edu

I'm a web applications developer trying to bring all things open source to all things humanities at Texas A&M University.

Journal of jsmith (3335)

Wednesday September 24, 2003
10:55 PM

First Post and eXtensible State Machines

[ #14891 ]

I'm on LiveJournal, but most of the people I know there aren't into Perl. This semester, I've been busy digging into a project that I've been working on for a year or so now. It's finally time to get it done. So, because I'm enthusiastic about it and spending long hours each day on it, I'll let some of that enthusiasm bubble over here.

I've been working on a XPath-like expression language for Perl data structures using Barrie Slaymaker's EventPath grammer which was based on James Clark's XPath grammer. I can now say /this/method::foo(/that)[@can="dance"] and get back any objects returned from the foo method of /this called with /that, and select those returned objects that can('dance'). Eventually I'll factor most of the code out and put it on CPAN as Data::DPath.

The Data::DPath stuff is the expression component of what I am calling eXtensible State Machines. These are like eXtensible Server Pages except they have no Perl (they are pure XML) and define the controller in an MVC application. The View is going to be provided by Template Toolkit (but that's configurable). I haven't decided what XSM will be called when I factor it out for CPAN.

The state machine compiler is borrowed from / based on the XSP compiler in AxKit. At this point, I'm more interested in it working correctly than efficiently. The data in the %EDGES hash is used to create Data::FormValidator objects to help decide which state to transition to. Of course, details are subject to change while in development.

<statemachine xmlns="http://some/url">
  <alias id="_begin" state="start"/>
  <state id="start">
    <transition state="edit">
      <variable id="uin"/>
      <group id="birth">
        <variable id="day"/>
        <variable id="month"/>
        <variable id="year"/>
      </group>
    </transition>
  </state>
  <state id="edit">
    <transition state="confirm">
      <variable id="netid"/>
      <variable id="password1"/>
      <variable id="password2"/>
      <script> <!-- defines the edit_to_confirm subroutine -->
        <assert test="not(string-cmp(/password1,/password2))" state="edit"/>
      </script>
    </transition>
  </state>
  <state id="confirm">
    <transition state="done">
      <variable id="confirm"/>
    </transition>
    <transition state="edit">
      <variable id="edit"/>
    </transition>
  </state>
</statemachine>

is compiled to the following Perl code:

package Gestinanna::Sites::Hinoto::XSM::activate::V1_5;
# line 555 "Perl generated by /usr/local/lib/perl5/site_perl/5.8.0/Gestinanna/XSM.pm"
#initialize sm namespace
sub edit_to_confirm {
    my ($sm) = shift;
    my %data = (
        local => $sm->data('out'),

        #session => $sm -> session,
        context => $sm->data, solar => {}, global => {},
    );

    return "edit" # <assert test="..." state="..."/>
      unless (
        (
         Gestinanna::XSM::Core::xsm_not(
             (
                 (
                     Gestinanna::XSM::Core::xsm_string_cmp(
                         (
                             grep { defined } map {
                                 Gestinanna::XSM::Expression::axis_child($_,
                                                                    "password1" )
                               } $data{"local"}
                         )[0],
                         (
                          grep { defined } map {
                              Gestinanna::XSM::Expression::axis_child($_,
                                                                    "password2" )
                            } $data{"local"}
                           )[0],
                     )
                 )
             )[0],
         )
        )
      );

    return;
} ## end sub edit_to_confirm
use vars qw(@ISA %HASA %VIEWS %ALIASES %EDGES);

@ISA     = ('Gestinanna::XSM::Base');
%HASA    = ();
%VIEWS   = ();
%ALIASES = ('_begin' => 'start');
%EDGES = (
       'confirm' => { 'done' => { 'required' => ['confirm'] },
                      'edit' => { 'required' => ['edit'] }
       },
       'edit' => # required to get from edit to confirm
         { 'confirm' => { 'required' => ['netid', 'password1', 'password2'] } },
       'start' => {
           'edit' => # required to get from start to edit
             { 'required' => ['uin', 'birth.day', 'birth.month', 'birth.year'] }
       }
);

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
 Full
 Abbreviated
 Hidden
More | Login | Reply
Loading... please wait.
  • I've been working on a XPath-like expression language for Perl data structures using Barrie Slaymaker's EventPath grammer which was based on James Clark's XPath grammer. I can now say /this/method::foo(/that)[@can="dance"] and get back any objects returned from the foo method of /this called with /that, and select those returned objects that can('dance'). Eventually I'll factor most of the code out and put it on CPAN as Data::DPath.

    After reading this journal entry, I thought you might find it interesting