> 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