> From: BenRifkah Bergsten-Buret [mailto:[EMAIL PROTECTED]

> Massive headaches.
Yup, I've been working on this, but I think I do have solution,
somewhat like you suggest below.

Background: I'm building common widgets, that I want to
grow increasingly in abstraction. I wanted a _common_ mechanism
to handle arguments. So I have a common set of <%once> and <%init>
statements for each widget. Problem of bundling statements into
a sub was that the common named sub seemed to be in the same
name space, which you confirm below. Hence it had access to
closure variables elsewhere, which was at first mystifying...

The solution has been to do:
my $initFunc = sub {
...code
};

Then &$initFunc. This is now lexical to the individual comp closure
if I understand correctly.

If using this technique, am I still going to cause myself
headaches somewhere that I've not considered?


> define a sub in a component it actually goes into the 
> HTML::Mason::Commands package.  The implications of this 

I figured that it was defining the sub name in a single namespace.

> depend on the 
> way you have Mason configured.  If you're running it within 
> mod_perl on 
> a standard Apache setup you have a persistent Perl machine that 
> maintains state from one web request to the next.

Yes, running in mod_perl, pre-fork.

> On top of that you 
> have multiple apache processes that can serve requests.

Ok, but one process will complete the request, not multiple processes.
Implications? As long as they are not multi-threaded?

> Using 
> subroutines in such a situation can lead to name space collisions and 
> intermittent race conditions.

I think I'm confused here. See below.
 
> An example of a race condition is when you build component A that 
> defines sub foo.  Noticing that this function is available to all 
> components and you use foo in component B.  In testing this may work 
> fine as long as component A is always called at least once IN EVERY 
> APACHE process before component B is ever called.

Ok, I'm thinking I understand... you define say sub named 'initFunc'
in comp A, but then want to call it in comp B. Yes, of course if B
tried to call it before A created it, then there is a problem.

My problem was that I was creating the exact same named function
in each of the widget comps, since each widget has its own closure and
the sub was defined in such a manner as to have access to the variables
in the closure. But that was the problem, there was _only_ one function
in the namespace, not one per component.

> However, 
> if you call 
> component B in an apache process that has yet to run 
> component A you'll 
> end up with an error saying that foo is not defined.  The 
> same thing can 
> happen when you restart the server.

Yes, you are right.

> If "foo" is something that should be called by more than one 
> component 
> it should be moved to its own component, defined as a <%method> of 
> component A, or as a function/method in an external Perl 
> module.

But that would then create a new closure, not having access to the
variables in the "parent" closure.

> You can do this:
> 
> <%once>
> my $foo = sub { stuff() };
> ...
> </%once>
> <% &$foo() %>

This is something along the lines of what I'm doing.
Instead of stuff() it is the statements.

So am I way off track in doing this? I want to munge the
lexical variables in the component, but don't want to have
to further ship them off to yet another routine. I'm
implementing something like a generic function, templated,
then instantiated into each component.

> Good luck,
> 
> -- Ben

Thanks, I really appreciate the feedback.

Best regards,

..Otto


-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Mason-users mailing list
Mason-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mason-users

Reply via email to