From granny+lapm at gmail.com Mon Jun 11 00:58:38 2012 From: granny+lapm at gmail.com (Andrew Grangaard) Date: Mon, 11 Jun 2012 00:58:38 -0700 Subject: [LA.pm] LA.pm Wed June 20, 2012. Message-ID: LA.pm's next meeting What: Los Angeles Perl Mongers Meeting When: 7-9pm Date: Wednesday June 20, 2012 Where: Demand Media, 1299 Ocean, Santa Monica, CA Theme: Perl! Refreshments: Food and BEvERages provided by Demand Media RSVP: Responses always appreciated. Presentations: Andrew Grangaard: YAPCna notes Abstract: Notes and discussion from YAPCna, June 13-15 in Madison, WI. You: TBD Abstract: Informal discussion of tools, comings and goings, etc. Ben Tilly: Template::ExpandHash (unconfirmed) Abstract: A new perl module to expand a hash as a template. Template::ExpandHash git Randal Schwartz: Testing Classes with Test::Trap (unconfirmed) RSVP via email or facebook : http://www.facebook.com/events/250417435064885 Hi Mongers! We voted at the May meeting, and I think we picked June 20 for our next meeting. [Backup date of thurs the 28th.] At Demand Media unless a compelling alternative offer is presented. :) I'll present on something from YAPCna [http://yapcna.org], which is in Madison,WI this week. We'll see if our previously offered presenters&presentations are still available from Merlyn and Ben. peace, andrew From btilly at gmail.com Mon Jun 11 07:47:35 2012 From: btilly at gmail.com (Ben Tilly) Date: Mon, 11 Jun 2012 07:47:35 -0700 Subject: [LA.pm] LA.pm Wed June 20, 2012. In-Reply-To: References: Message-ID: I can tentatively commit. It looks like my wife can take the kids that night. On Mon, Jun 11, 2012 at 12:58 AM, Andrew Grangaard wrote: > LA.pm's next meeting > > What: ? ?Los Angeles Perl Mongers Meeting > When: ? ?7-9pm > Date: ? ?Wednesday June 20, 2012 > Where: ? Demand Media, 1299 Ocean, Santa Monica, CA > Theme: ? Perl! > Refreshments: ? ?Food and BEvERages provided by Demand Media > RSVP: ? ?Responses always appreciated. > Presentations: > > Andrew Grangaard: YAPCna notes > Abstract: Notes and discussion from YAPCna, June 13-15 in Madison, WI. > You: TBD > Abstract: Informal discussion of tools, comings and goings, etc. > Ben Tilly: Template::ExpandHash (unconfirmed) > Abstract: A new perl module to expand a hash as a template. > Template::ExpandHash git > Randal Schwartz: Testing Classes with Test::Trap (unconfirmed) > > RSVP via email or facebook : http://www.facebook.com/events/250417435064885 > > Hi Mongers! ?We voted at the May meeting, and I think we picked June > 20 for our next meeting. ?[Backup date of thurs the 28th.] ?At Demand > Media unless a compelling alternative offer is presented. :) > > I'll present on something from YAPCna [http://yapcna.org], which is in > Madison,WI this week. ? ?We'll see if our previously offered > presenters&presentations are still available from Merlyn and Ben. > > peace, > andrew > _______________________________________________ > Losangeles-pm mailing list > Losangeles-pm at pm.org > http://mail.pm.org/mailman/listinfo/losangeles-pm From granny+lapm at gmail.com Wed Jun 20 16:52:30 2012 From: granny+lapm at gmail.com (Andrew Grangaard) Date: Wed, 20 Jun 2012 23:52:30 +0000 Subject: [LA.pm] LA.pm Wed June 20, 2012. In-Reply-To: References: Message-ID: Hi Mongers! Looking forward to seeing you tonight. YAPC.na was awesome last week, can't wait to share the buzz with y'all. Andrew On Mon, Jun 11, 2012 at 7:58 AM, Andrew Grangaard wrote: > LA.pm's next meeting > > What: ? ?Los Angeles Perl Mongers Meeting > When: ? ?7-9pm > Date: ? ?Wednesday June 20, 2012 > Where: ? Demand Media, 1299 Ocean, Santa Monica, CA > Theme: ? Perl! > Refreshments: ? ?Food and BEvERages provided by Demand Media > RSVP: ? ?Responses always appreciated. > Presentations: > > Andrew Grangaard: YAPCna notes > Abstract: Notes and discussion from YAPCna, June 13-15 in Madison, WI. > Ben Tilly: Template::ExpandHash (unconfirmed) > Abstract: A new perl module to expand a hash as a template. > Template::ExpandHash git > > RSVP via email or facebook : http://www.facebook.com/events/250417435064885 > > Hi Mongers! ?We voted at the May meeting, and I think we picked June > 20 for our next meeting. ?[Backup date of thurs the 28th.] ?At Demand > Media unless a compelling alternative offer is presented. :) > > I'll present on something from YAPCna [http://yapcna.org], which is in > Madison,WI this week. ? ?We'll see if our previously offered > presenters&presentations are still available from Merlyn and Ben. > > peace, > andrew From btilly at gmail.com Thu Jun 21 01:20:00 2012 From: btilly at gmail.com (Ben Tilly) Date: Thu, 21 Jun 2012 01:20:00 -0700 Subject: [LA.pm] Thanks for letting me present Message-ID: I have put my presentation up at http://elem.com/~btilly/template-hashexpand/ for anyone who wants to go through the slides. I gave thought to Eric's comment about adding looping, and came up with a weird suggestion for how to do it. Add function calls to code references stored elsewhere in the hash. So we might allow: { joiner => sub { my ($expander, $hashref, $sep, @args) = @_; return join $sep, @args; }, foo => '{% joiner( ' ', Hello, world) %}', } And this would expand to: { joiner => sub { my ($expander, $hashref, $sep, @args) = @_; return join $sep, @args; }, foo => 'Hello world', } *However* the function would have complete access to an object that can trigger hash expansion inside of the current context, and also the hash reference. So if you wanted to, you could have it loop, and insert a bunch of stuff into the hash, using hash expansion to customize them. Thus you can have your config expansion insert this looping capability, and then you can use it wherever it makes sense. Let's take this idea a few steps further off towards insanity. The next utility step would be to allow multi-level expansion in a string. So, for instance, you can have: { foo => '[% foo[% bar %] %]', bar => 'blat', fooblat => 'gotcha', } which would expand to: { foo => 'gotcha', bar => 'blat', fooblat => 'gotcha', } But you could do this with function calls instead if you wanted. So one parameter can be expanded to something dynamically determined by another parameter. (You could implement this yourself inside of the function, but why not make it easy.) The third step is that if a template expansion is *exactly* a variable expansion, we get that value inserted as is (instead of stringified). So: { foo => { this => 'that', }, bar => '[% foo %]', } should expand to: { foo => { this => 'that', }, bar => { this => 'that', }, } Combined with the second step, this would allow us to pass real data structures to function calls inside of hash values that we are expanding. And while we're at it, we can always allow an easier quoted string syntax. So for instance no expansion would happen if you started the string with %%. So: { foo => '%%[% Hello %]', } would expand to: { foo => '[% Hello %]', } Now if you squint right, the ability to call functions looks like Lisp macros. The ability to suppress template expansion before the call, then have it happen inside of the function gives us an equivalent to Lisp macros. And we can implement the special forms directly in Perl functions. Any template expansion system that gives you something with a recognizable parallel to Lisp (albeit with a different syntax) qualifies in my books as "sufficiently powerful" for any reasonable need... Does anyone have any reaction other than, "He just went off the deep end"? From btilly at gmail.com Thu Jun 21 02:05:23 2012 From: btilly at gmail.com (Ben Tilly) Date: Thu, 21 Jun 2012 02:05:23 -0700 Subject: [LA.pm] Thanks for letting me present In-Reply-To: References: Message-ID: Hrm, I guess I gave all of the architecture, but didn't show what the answer to Eric's problem could look like. Let me do that. { range => sub { my ($expander, $hashref, $from, $to) = @_; return [$from..$to]; }, insert_foreach => sub { my ($expander, $hashref, $var, $range, $key, $value) = @_; for (@$range) { my $expanded = $expander->expand({ $var => $_, key => $key, value => $value, }); $hashref->{$expanded->{$key}} = $expanded->{$value}; } return undef; # We do not use this again. }, subdomain_count => 5, subdomain_template => { domain => '%%m[% i %].campusexplorer.com', foo => 'bar', }, dummy => '[% insert_foreach( i, [% range(1, [% subdomain_count %]) %], %%m[%i], [% subdomain_template %], ) %]', } And then expanded we would get: { range => sub { my ($expander, $hashref, $from, $to) = @_; return [$from..$to]; }, insert_foreach => sub { my ($expander, $hashref, $var, $range, $key, $value) = @_; for (@$range) { my $expanded = $expander->expand({ $var => $_, key => $key, value => $value, }); $hashref->{$expanded->{$key}} = $expanded->{$value}; } return undef; # We do not use this again. }, subdomain_count => 5, subdomain_template => { domain => 'm[% i %].campusexplorer.com', foo => 'bar', }, dummy => undef, m1 => { domain => 'm1.campusexplorer.com', foo => 'bar', }, m2 => { domain => 'm2.campusexplorer.com', foo => 'bar', }, m3 => { domain => 'm3.campusexplorer.com', foo => 'bar', }, m4 => { domain => 'm4.campusexplorer.com', foo => 'bar', }, m5 => { domain => 'm5.campusexplorer.com', foo => 'bar', }, } I guess that it is a matter of opinion whether this proposed cure is worse than the disease... By the way where I randomly chose %%, a better Lisp analogy would be ` (backtick). On Thu, Jun 21, 2012 at 1:20 AM, Ben Tilly wrote: > I have put my presentation up at > http://elem.com/~btilly/template-hashexpand/ for anyone who wants to > go through the slides. > > I gave thought to Eric's comment about adding looping, and came up > with a weird suggestion for how to do it. ?Add function calls to code > references stored elsewhere in the hash. ?So we might allow: > > ?{ > ? ?joiner => sub { > ? ? ?my ($expander, $hashref, $sep, @args) = @_; > ? ? ?return join $sep, @args; > ? ?}, > ? ?foo => '{% joiner( ' ', Hello, world) %}', > ?} > > And this would expand to: > > ?{ > ? ?joiner => sub { > ? ? ?my ($expander, $hashref, $sep, @args) = @_; > ? ? ?return join $sep, @args; > ? ?}, > ? ?foo => 'Hello world', > ?} > > *However* the function would have complete access to an object that > can trigger hash expansion inside of the current context, and also the > hash reference. ?So if you wanted to, you could have it loop, and > insert a bunch of stuff into the hash, using hash expansion to > customize them. ?Thus you can have your config expansion insert this > looping capability, and then you can use it wherever it makes sense. > > Let's take this idea a few steps further off towards insanity. ?The > next utility step would be to allow multi-level expansion in a string. > ?So, for instance, you can have: > > ?{ > ? ?foo => '[% foo[% bar %] %]', > ? ?bar => 'blat', > ? ?fooblat => 'gotcha', > ?} > > which would expand to: > > ?{ > ? ?foo => 'gotcha', > ? ?bar => 'blat', > ? ?fooblat => 'gotcha', > ?} > > But you could do this with function calls instead if you wanted. ?So > one parameter can be expanded to something dynamically determined by > another parameter. ?(You could implement this yourself inside of the > function, but why not make it easy.) > > The third step is that if a template expansion is *exactly* a variable > expansion, we get that value inserted as is (instead of stringified). > So: > > ?{ > ? ?foo => { > ? ? ?this => 'that', > ? ?}, > ? ?bar => '[% foo %]', > ?} > > should expand to: > > ?{ > ? ?foo => { > ? ? ?this => 'that', > ? ?}, > ? ?bar => { > ? ? ?this => 'that', > ? ?}, > ?} > > Combined with the second step, this would allow us to pass real data > structures to function calls inside of hash values that we are > expanding. > > And while we're at it, we can always allow an easier quoted string > syntax. ?So for instance no expansion would happen if you started the > string with %%. ?So: > > ?{ > ? ?foo => '%%[% Hello %]', > ?} > > would expand to: > > ?{ > ? ?foo => '[% Hello %]', > ?} > > Now if you squint right, the ability to call functions looks like Lisp > macros. ?The ability to suppress template expansion before the call, > then have it happen inside of the function gives us an equivalent to > Lisp macros. ?And we can implement the special forms directly in Perl > functions. > > Any template expansion system that gives you something with a > recognizable parallel to Lisp (albeit with a different syntax) > qualifies in my books as "sufficiently powerful" for any reasonable > need... > > Does anyone have any reaction other than, "He just went off the deep end"? From daoswald at gmail.com Thu Jun 21 11:37:17 2012 From: daoswald at gmail.com (David Oswald) Date: Thu, 21 Jun 2012 11:37:17 -0700 Subject: [LA.pm] Thanks for letting me present In-Reply-To: References: Message-ID: On Thu, Jun 21, 2012 at 2:05 AM, Ben Tilly wrote: > Hrm, I guess I gave all of the architecture, but didn't show what the > answer to Eric's problem could look like. ?Let me do that. > > ? ?insert_foreach => sub { > ? ? ?my ($expander, $hashref, $var, $range, $key, $value) = @_; > ? ? ?for (@$range) { > ? ? ? ?my $expanded = $expander->expand({ > ? ? ? ? ?$var => $_, > ? ? ? ? ?key => $key, > ? ? ? ? ?value => $value, > ? ? ? ?}); > ? ? ? ?$hashref->{$expanded->{$key}} = $expanded->{$value}; > ? ? ?} > ? ? ?return undef; # We do not use this again. > ? ?}, Interesting approach... I see how it works, but someone with such a need might not immediately think of it. Perhaps you could provide a "cookbook" POD document with your module. Just a thought for version 0.02. :) By the way, from perldoc perlre: "The \A and \Z are just like "^" and "$", except that they won't match multiple times when the /m modifier is used, while "^" and "$" will match at every internal line boundary. To match the actual end of the string and not ignore an optional trailing newline, use \z ." So your ^ .... \z is obviously OK since it should be impossible to match multiple times at the beginning of a line (^) if you're anchoring to the end of the string with \z... and of course you're not even using the /m modifier, so the discussion is just theoretical. I suppose someone could write something like this: /(?:^[^\n]+\n)+\z/ and end up matching multiple lines despite the \z anchor, but it seems not that useful. _____ ...... ----- A tangent we visited last night: Version numbers ----- ...... _____ I was thinking more about the version numbering question. ...again this is theoretical because nobody is actually suggesting that one SHOULD use a version 0.00, but the question of whether one COULD came up. I think there are risks. Of course the string '0.00' evaluates to true under the "zero but true" rule. But code that treats a version number numerically would get a numeric evaluation of the string. Subsequent Boolean tests would get 'false'. our $VERSION = '0.00'; # Boolean test is based on the string value: True. if( $VERSION && $VERSION =~ /^[0.]+$/ ) { warn "Zero but true."; # Numeric relational comparison: From this point forward # Boolean tests will be based on numeric value: False. if( $VERSION < 0.02 ) { warn "We prefer a more stable version!"; # Naive test... if( ! $VERSION ) { warn "Zero and false."; } This is a contrived example, but without diving into the internals of ExtUtils::MakeMaker, Module::Build, and all the other entities that look at version numbers, it's impossible to be certain that a zero for a version number wouldn't break something. ...and it probably would only break something on a production machine six months from now when someone upgrades a seemingly unrelated module. Actually perldoc perlmodlib does provide a suggestion that if implemented would break a zero-based version number. Developer's release version numbers. our $VERSION = '0.00_00'; $VERSION = eval $VERSION; >From perlmodstyle: "With that trick MakeMaker will only read the first line and thus read the underscore [treating this as a developer's release], while the perl interpreter will evaluate the $VERSION and convert the string into a number. Later operations that treat $VERSION as a number will then be able to do so without provoking a warning about $VERSION not being a number." That's fine for version numbers that evaluate to Boolean true, but somewhere, someday there will be some module that interacts with ours and does a Boolean test of the version number. It's bound to cause an element of surprise somewhere. I don't think anyone looks to me as an authority on PAUSE, EU::MM, and so on... but I'll go ahead and suggest it anyway: Although one probably COULD, one definitely SHOULD NOT use any form of zero or zero string as a version number. Behavior is too unpredictable. Dave -- David Oswald daoswald at gmail.com From btilly at gmail.com Thu Jun 21 13:06:04 2012 From: btilly at gmail.com (Ben Tilly) Date: Thu, 21 Jun 2012 13:06:04 -0700 Subject: [LA.pm] Thanks for letting me present In-Reply-To: References: Message-ID: On Thu, Jun 21, 2012 at 11:37 AM, David Oswald wrote: > On Thu, Jun 21, 2012 at 2:05 AM, Ben Tilly wrote: >> Hrm, I guess I gave all of the architecture, but didn't show what the >> answer to Eric's problem could look like. ?Let me do that. >> > > > >> ? ?insert_foreach => sub { >> ? ? ?my ($expander, $hashref, $var, $range, $key, $value) = @_; >> ? ? ?for (@$range) { >> ? ? ? ?my $expanded = $expander->expand({ >> ? ? ? ? ?$var => $_, >> ? ? ? ? ?key => $key, >> ? ? ? ? ?value => $value, >> ? ? ? ?}); >> ? ? ? ?$hashref->{$expanded->{$key}} = $expanded->{$value}; >> ? ? ?} >> ? ? ?return undef; # We do not use this again. >> ? ?}, > > > > Interesting approach... I see how it works, but someone with such a > need might not immediately think of it. ?Perhaps you could provide a > "cookbook" POD document with your module. > Just a thought for version 0.02. :) Heh, you think I'm adding this in version 0.02?? I thought more about it. If I went down this road, I'd be inclined to make it more lisp-like, and have some useful functionality available by default so that people don't need to write those messy bits. That would reduce Eric's solution to something like this: { subdomain_count => 5, subdomain_template => { domain => '`m[% i %].campusexplorer.com', foo => 'bar', }, dummy => '[% foreach i [% range 1 [% subdomain_count %] %] [% insert m[% i %] [% subdomain_template %] %]', } Which would expand to: { subdomain_count => 5, subdomain_template => { domain => 'm[% i %].campusexplorer.com', foo => 'bar', }, m1 => { domain => 'm1.campusexplorer.com', foo => 'bar', }, m2 => { domain => 'm2.campusexplorer.com', foo => 'bar', }, m3 => { domain => 'm3.campusexplorer.com', foo => 'bar', }, m4 => { domain => 'm4.campusexplorer.com', foo => 'bar', }, m5 => { domain => 'm5.campusexplorer.com', foo => 'bar', }, } Add configurability for the delimiters, add a convenient set of built-ins, and you really would have a recognizable (though small) Lisp. But I'm not sure whether anyone but me would find this approach comfortable. > By the way, from perldoc perlre: > > "The \A and \Z are just like "^" and "$", except that they won't match > multiple times when the /m modifier is used, while "^" and "$" will > match at every internal line boundary. To match the actual end of the > string and not ignore an optional trailing newline, use \z ." > > So your ^ .... \z is obviously OK since it should be impossible to > match multiple times at the beginning of a line (^) if you're > anchoring to the end of the string with \z... and of course you're not > even using the /m modifier, so the discussion is just theoretical. ?I > suppose someone could write something like this: ?/(?:^[^\n]+\n)+\z/ > and end up matching multiple lines despite the \z anchor, but it seems > not that useful. Ah right. Now I vaguely remember having looked at \A and \Z and having concluded that I almost never would want to use them, and therefore shouldn't try to memorize them. > _____ ...... ----- A tangent we visited last night: Version numbers > ----- ...... _____ > > I was thinking more about the version numbering question. ?...again > this is theoretical because nobody is actually suggesting that one > SHOULD use a version 0.00, but the question of whether one COULD came > up. ?I think there are risks. ?Of course the string '0.00' evaluates > to true under the "zero but true" rule. ?But code that treats a > version number numerically would get a numeric evaluation of the > string. ?Subsequent Boolean tests would get 'false'. > > our $VERSION = '0.00'; > > # Boolean test is based on the string value: True. > if( $VERSION && $VERSION =~ /^[0.]+$/ ) { > ? ?warn "Zero but true."; > > # Numeric relational comparison: From this point forward > # Boolean tests will be based on numeric value: False. > if( $VERSION < 0.02 ) { > ? ?warn "We prefer a more stable version!"; > > # Naive test... > if( ! $VERSION ) { > ? ?warn "Zero and false."; > } > > This is a contrived example, but without diving into the internals of > ExtUtils::MakeMaker, Module::Build, and all the other entities that > look at version numbers, it's impossible to be certain that a zero for > a version number wouldn't break something. ?...and it probably would > only break something on a production machine six months from now when > someone upgrades a seemingly unrelated module. > > Actually perldoc perlmodlib does provide a suggestion that if > implemented would break a zero-based version number. ?Developer's > release version numbers. > > our $VERSION = '0.00_00'; > $VERSION = eval $VERSION; > > From perlmodstyle: "With that trick MakeMaker will only read the first > line and thus read the underscore [treating this as a developer's > release], while the perl interpreter will evaluate the $VERSION and > convert the string into a number. Later operations that treat $VERSION > as a number will then be able to do so without provoking a warning > about $VERSION not being a number." > > That's fine for version numbers that evaluate to Boolean true, but > somewhere, someday there will be some module that interacts with ours > and does a Boolean test of the version number. ?It's bound to cause an > element of surprise somewhere. > > I don't think anyone looks to me as an authority on PAUSE, EU::MM, and > so on... but I'll go ahead and suggest it anyway: Although one > probably COULD, one definitely SHOULD NOT use any form of zero or zero > string as a version number. ?Behavior is too unpredictable. I'm glad that your more in depth analysis agreed with our gut reaction last night. From merlyn at stonehenge.com Thu Jun 21 13:35:10 2012 From: merlyn at stonehenge.com (Randal L. Schwartz) Date: Thu, 21 Jun 2012 13:35:10 -0700 Subject: [LA.pm] Thanks for letting me present In-Reply-To: (Ben Tilly's message of "Thu, 21 Jun 2012 13:06:04 -0700") References: Message-ID: <86wr309zep.fsf@red.stonehenge.com> >>>>> "Ben" == Ben Tilly writes: Ben> I thought more about it. If I went down this road, I'd be inclined to Ben> make it more lisp-like, and have some useful functionality available Ben> by default so that people don't need to write those messy bits. That Ben> would reduce Eric's solution to something like this: "And once again, a massive templating system was formed, from the seed of a 'keep it simple' start..." :-) -- Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095 Smalltalk/Perl/Unix consulting, Technical writing, Comedy, etc. etc. See http://methodsandmessages.posterous.com/ for Smalltalk discussion From btilly at gmail.com Thu Jun 21 14:24:01 2012 From: btilly at gmail.com (Ben Tilly) Date: Thu, 21 Jun 2012 14:24:01 -0700 Subject: [LA.pm] Thanks for letting me present In-Reply-To: <86wr309zep.fsf@red.stonehenge.com> References: <86wr309zep.fsf@red.stonehenge.com> Message-ID: On Thu, Jun 21, 2012 at 1:35 PM, Randal L. Schwartz wrote: >>>>>> "Ben" == Ben Tilly writes: > > Ben> I thought more about it. ?If I went down this road, I'd be inclined to > Ben> make it more lisp-like, and have some useful functionality available > Ben> by default so that people don't need to write those messy bits. ?That > Ben> would reduce Eric's solution to something like this: > > "And once again, a massive templating system was formed, from the seed > of a 'keep it simple' start..." > > :-) It hasn't happened yet. So far it is all an exercise in armchair language design. And won't happen unless someone actually seems to need this kind of functionality. (Eric suggested that he has a use case, but I'm not sure it is worthwhile.) That said, if I was to build a "massive templating system", there are worse places to draw inspiration from than Lisp... From uri at stemsystems.com Thu Jun 21 14:32:40 2012 From: uri at stemsystems.com (Uri Guttman) Date: Thu, 21 Jun 2012 17:32:40 -0400 Subject: [LA.pm] Thanks for letting me present In-Reply-To: <86wr309zep.fsf@red.stonehenge.com> References: <86wr309zep.fsf@red.stonehenge.com> Message-ID: <4FE392F8.4090709@stemsystems.com> On 06/21/2012 04:35 PM, Randal L. Schwartz wrote: >>>>>> "Ben" == Ben Tilly writes: > > Ben> I thought more about it. If I went down this road, I'd be inclined to > Ben> make it more lisp-like, and have some useful functionality available > Ben> by default so that people don't need to write those messy bits. That > Ben> would reduce Eric's solution to something like this: > > "And once again, a massive templating system was formed, from the seed > of a 'keep it simple' start..." > > :-) hey, i already have the template::simple territory! and it has not grown at all other than adding a compiler for speed. a recent patch allowed for user supplied token matching (he wanted - in the tokens). not what i call bloat. :) uri From merlyn at stonehenge.com Thu Jun 21 14:57:07 2012 From: merlyn at stonehenge.com (Randal L. Schwartz) Date: Thu, 21 Jun 2012 14:57:07 -0700 Subject: [LA.pm] Thanks for letting me present In-Reply-To: (Ben Tilly's message of "Thu, 21 Jun 2012 14:24:01 -0700") References: <86wr309zep.fsf@red.stonehenge.com> Message-ID: <86lijg9vm4.fsf@red.stonehenge.com> >>>>> "Ben" == Ben Tilly writes: Ben> That said, if I was to build a "massive templating system", there are Ben> worse places to draw inspiration from than Lisp... *cough* template *cough* toolkit *cough* :-) -- Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095 Smalltalk/Perl/Unix consulting, Technical writing, Comedy, etc. etc. See http://methodsandmessages.posterous.com/ for Smalltalk discussion From eric at perl.org Thu Jun 21 15:04:44 2012 From: eric at perl.org (Eric Hammond) Date: Thu, 21 Jun 2012 15:04:44 -0700 Subject: [LA.pm] [perl-org] Re: Thanks for letting me present In-Reply-To: References: Message-ID: <4FE39A7C.8070003@perl.org> Is it too late to say "I was joking"? Once it gets that complicated, how about just running YAML files through Template::Toolkit? Existing components, powerful, and well understood. BTW, Thanks for presenting, Ben. I loved the mix of theory and practice. -- Eric Hammond On 06/21/2012 02:05 AM, Ben Tilly wrote: > Hrm, I guess I gave all of the architecture, but didn't show what the > answer to Eric's problem could look like. Let me do that. > > { > range => sub { > my ($expander, $hashref, $from, $to) = @_; > return [$from..$to]; > }, > insert_foreach => sub { > my ($expander, $hashref, $var, $range, $key, $value) = @_; > for (@$range) { > my $expanded = $expander->expand({ > $var => $_, > key => $key, > value => $value, > }); > $hashref->{$expanded->{$key}} = $expanded->{$value}; > } > return undef; # We do not use this again. > }, > subdomain_count => 5, > subdomain_template => { > domain => '%%m[% i %].campusexplorer.com', > foo => 'bar', > }, > dummy => '[% > insert_foreach( > i, > [% range(1, [% subdomain_count %]) %], > %%m[%i], > [% subdomain_template %], > ) %]', > } > > And then expanded we would get: > > { > range => sub { > my ($expander, $hashref, $from, $to) = @_; > return [$from..$to]; > }, > insert_foreach => sub { > my ($expander, $hashref, $var, $range, $key, $value) = @_; > for (@$range) { > my $expanded = $expander->expand({ > $var => $_, > key => $key, > value => $value, > }); > $hashref->{$expanded->{$key}} = $expanded->{$value}; > } > return undef; # We do not use this again. > }, > subdomain_count => 5, > subdomain_template => { > domain => 'm[% i %].campusexplorer.com', > foo => 'bar', > }, > dummy => undef, > m1 => { > domain => 'm1.campusexplorer.com', > foo => 'bar', > }, > m2 => { > domain => 'm2.campusexplorer.com', > foo => 'bar', > }, > m3 => { > domain => 'm3.campusexplorer.com', > foo => 'bar', > }, > m4 => { > domain => 'm4.campusexplorer.com', > foo => 'bar', > }, > m5 => { > domain => 'm5.campusexplorer.com', > foo => 'bar', > }, > } > > I guess that it is a matter of opinion whether this proposed cure is > worse than the disease... > > By the way where I randomly chose %%, a better Lisp analogy would be ` > (backtick). > > On Thu, Jun 21, 2012 at 1:20 AM, Ben Tilly wrote: >> I have put my presentation up at >> http://elem.com/~btilly/template-hashexpand/ for anyone who wants to >> go through the slides. >> >> I gave thought to Eric's comment about adding looping, and came up >> with a weird suggestion for how to do it. Add function calls to code >> references stored elsewhere in the hash. So we might allow: >> >> { >> joiner => sub { >> my ($expander, $hashref, $sep, @args) = @_; >> return join $sep, @args; >> }, >> foo => '{% joiner( ' ', Hello, world) %}', >> } >> >> And this would expand to: >> >> { >> joiner => sub { >> my ($expander, $hashref, $sep, @args) = @_; >> return join $sep, @args; >> }, >> foo => 'Hello world', >> } >> >> *However* the function would have complete access to an object that >> can trigger hash expansion inside of the current context, and also the >> hash reference. So if you wanted to, you could have it loop, and >> insert a bunch of stuff into the hash, using hash expansion to >> customize them. Thus you can have your config expansion insert this >> looping capability, and then you can use it wherever it makes sense. >> >> Let's take this idea a few steps further off towards insanity. The >> next utility step would be to allow multi-level expansion in a string. >> So, for instance, you can have: >> >> { >> foo => '[% foo[% bar %] %]', >> bar => 'blat', >> fooblat => 'gotcha', >> } >> >> which would expand to: >> >> { >> foo => 'gotcha', >> bar => 'blat', >> fooblat => 'gotcha', >> } >> >> But you could do this with function calls instead if you wanted. So >> one parameter can be expanded to something dynamically determined by >> another parameter. (You could implement this yourself inside of the >> function, but why not make it easy.) >> >> The third step is that if a template expansion is *exactly* a variable >> expansion, we get that value inserted as is (instead of stringified). >> So: >> >> { >> foo => { >> this => 'that', >> }, >> bar => '[% foo %]', >> } >> >> should expand to: >> >> { >> foo => { >> this => 'that', >> }, >> bar => { >> this => 'that', >> }, >> } >> >> Combined with the second step, this would allow us to pass real data >> structures to function calls inside of hash values that we are >> expanding. >> >> And while we're at it, we can always allow an easier quoted string >> syntax. So for instance no expansion would happen if you started the >> string with %%. So: >> >> { >> foo => '%%[% Hello %]', >> } >> >> would expand to: >> >> { >> foo => '[% Hello %]', >> } >> >> Now if you squint right, the ability to call functions looks like Lisp >> macros. The ability to suppress template expansion before the call, >> then have it happen inside of the function gives us an equivalent to >> Lisp macros. And we can implement the special forms directly in Perl >> functions. >> >> Any template expansion system that gives you something with a >> recognizable parallel to Lisp (albeit with a different syntax) >> qualifies in my books as "sufficiently powerful" for any reasonable >> need... >> >> Does anyone have any reaction other than, "He just went off the deep end"? > _______________________________________________ > Losangeles-pm mailing list > Losangeles-pm at pm.org > http://mail.pm.org/mailman/listinfo/losangeles-pm > From btilly at gmail.com Thu Jun 21 15:28:03 2012 From: btilly at gmail.com (Ben Tilly) Date: Thu, 21 Jun 2012 15:28:03 -0700 Subject: [LA.pm] Thanks for letting me present In-Reply-To: <86lijg9vm4.fsf@red.stonehenge.com> References: <86wr309zep.fsf@red.stonehenge.com> <86lijg9vm4.fsf@red.stonehenge.com> Message-ID: On Thu, Jun 21, 2012 at 2:57 PM, Randal L. Schwartz wrote: >>>>>> "Ben" == Ben Tilly writes: > > Ben> That said, if I was to build a "massive templating system", there are > Ben> worse places to draw inspiration from than Lisp... > > *cough* template *cough* toolkit *cough* > > :-) As I was saying... ;-) More seriously, when I see template toolkit, I see something that lets you apply data to structured text with a familiar imperative syntax, and get back repetitive text. By contrast when I see Lisp I see something which is easier to implement that lets you apply a data structure to a data structure and get back a transformed data structure. That to me looks more like, "Take a nested hash, get back a nested hash with some repetitive stuff in it." But the point is moot, since I'm not building it. From btilly at gmail.com Thu Jun 21 15:38:10 2012 From: btilly at gmail.com (Ben Tilly) Date: Thu, 21 Jun 2012 15:38:10 -0700 Subject: [LA.pm] [perl-org] Re: Thanks for letting me present In-Reply-To: <4FE39A7C.8070003@perl.org> References: <4FE39A7C.8070003@perl.org> Message-ID: I took this too seriously because it was a fun problem to think about while I was loopy on the caffeine that I used to stay awake on my way home... As for YAML files through Template::Toolkit, there is a bootstrap problem. Where do you get the parameters that you will use to expand those templates? From the same configuration that you're generating out of the parsed output? It seems to me that a better hack is to generate that part of the hash from a map statement that exists in pure Perl. (Even if you're using YAML for most of your data, if you use the Config::Any solution I showed to load it, you can easily generate part of your configuration in pure Perl.) The limitation is that you don't have the easy option to modify that map statement based on an override in a child hash. But that's probably not a significant limitation. On Thu, Jun 21, 2012 at 3:04 PM, Eric Hammond wrote: > > Is it too late to say "I was joking"? > > Once it gets that complicated, how about just running YAML files through > Template::Toolkit? ?Existing components, powerful, and well understood. > > BTW, Thanks for presenting, Ben. ?I loved the mix of theory and practice. > > -- > Eric Hammond > > On 06/21/2012 02:05 AM, Ben Tilly wrote: >> Hrm, I guess I gave all of the architecture, but didn't show what the >> answer to Eric's problem could look like. ?Let me do that. >> >> ? { >> ? ? range => sub { >> ? ? ? my ($expander, $hashref, $from, $to) = @_; >> ? ? ? return [$from..$to]; >> ? ? }, >> ? ? insert_foreach => sub { >> ? ? ? my ($expander, $hashref, $var, $range, $key, $value) = @_; >> ? ? ? for (@$range) { >> ? ? ? ? my $expanded = $expander->expand({ >> ? ? ? ? ? $var => $_, >> ? ? ? ? ? key => $key, >> ? ? ? ? ? value => $value, >> ? ? ? ? }); >> ? ? ? ? $hashref->{$expanded->{$key}} = $expanded->{$value}; >> ? ? ? } >> ? ? ? return undef; # We do not use this again. >> ? ? }, >> ? ? subdomain_count => 5, >> ? ? subdomain_template => { >> ? ? ? domain => '%%m[% i %].campusexplorer.com', >> ? ? ? foo => 'bar', >> ? ? }, >> ? ? dummy => '[% >> ? ? ? ? insert_foreach( >> ? ? ? ? ? i, >> ? ? ? ? ? [% range(1, [% subdomain_count %]) %], >> ? ? ? ? ? %%m[%i], >> ? ? ? ? ? [% subdomain_template %], >> ? ? ? ? ) %]', >> ? } >> >> And then expanded we would get: >> >> ? { >> ? ? range => sub { >> ? ? ? my ($expander, $hashref, $from, $to) = @_; >> ? ? ? return [$from..$to]; >> ? ? }, >> ? ? insert_foreach => sub { >> ? ? ? my ($expander, $hashref, $var, $range, $key, $value) = @_; >> ? ? ? for (@$range) { >> ? ? ? ? my $expanded = $expander->expand({ >> ? ? ? ? ? $var => $_, >> ? ? ? ? ? key => $key, >> ? ? ? ? ? value => $value, >> ? ? ? ? }); >> ? ? ? ? $hashref->{$expanded->{$key}} = $expanded->{$value}; >> ? ? ? } >> ? ? ? return undef; # We do not use this again. >> ? ? }, >> ? ? subdomain_count => 5, >> ? ? subdomain_template => { >> ? ? ? domain => 'm[% i %].campusexplorer.com', >> ? ? ? foo => 'bar', >> ? ? }, >> ? ? dummy => undef, >> ? ? m1 => { >> ? ? ? domain => 'm1.campusexplorer.com', >> ? ? ? foo => 'bar', >> ? ? }, >> ? ? m2 => { >> ? ? ? domain => 'm2.campusexplorer.com', >> ? ? ? foo => 'bar', >> ? ? }, >> ? ? m3 => { >> ? ? ? domain => 'm3.campusexplorer.com', >> ? ? ? foo => 'bar', >> ? ? }, >> ? ? m4 => { >> ? ? ? domain => 'm4.campusexplorer.com', >> ? ? ? foo => 'bar', >> ? ? }, >> ? ? m5 => { >> ? ? ? domain => 'm5.campusexplorer.com', >> ? ? ? foo => 'bar', >> ? ? }, >> ? } >> >> I guess that it is a matter of opinion whether this proposed cure is >> worse than the disease... >> >> By the way where I randomly chose %%, a better Lisp analogy would be ` >> (backtick). >> >> On Thu, Jun 21, 2012 at 1:20 AM, Ben Tilly wrote: >>> I have put my presentation up at >>> http://elem.com/~btilly/template-hashexpand/ for anyone who wants to >>> go through the slides. >>> >>> I gave thought to Eric's comment about adding looping, and came up >>> with a weird suggestion for how to do it. ?Add function calls to code >>> references stored elsewhere in the hash. ?So we might allow: >>> >>> ?{ >>> ? ?joiner => sub { >>> ? ? ?my ($expander, $hashref, $sep, @args) = @_; >>> ? ? ?return join $sep, @args; >>> ? ?}, >>> ? ?foo => '{% joiner( ' ', Hello, world) %}', >>> ?} >>> >>> And this would expand to: >>> >>> ?{ >>> ? ?joiner => sub { >>> ? ? ?my ($expander, $hashref, $sep, @args) = @_; >>> ? ? ?return join $sep, @args; >>> ? ?}, >>> ? ?foo => 'Hello world', >>> ?} >>> >>> *However* the function would have complete access to an object that >>> can trigger hash expansion inside of the current context, and also the >>> hash reference. ?So if you wanted to, you could have it loop, and >>> insert a bunch of stuff into the hash, using hash expansion to >>> customize them. ?Thus you can have your config expansion insert this >>> looping capability, and then you can use it wherever it makes sense. >>> >>> Let's take this idea a few steps further off towards insanity. ?The >>> next utility step would be to allow multi-level expansion in a string. >>> ?So, for instance, you can have: >>> >>> ?{ >>> ? ?foo => '[% foo[% bar %] %]', >>> ? ?bar => 'blat', >>> ? ?fooblat => 'gotcha', >>> ?} >>> >>> which would expand to: >>> >>> ?{ >>> ? ?foo => 'gotcha', >>> ? ?bar => 'blat', >>> ? ?fooblat => 'gotcha', >>> ?} >>> >>> But you could do this with function calls instead if you wanted. ?So >>> one parameter can be expanded to something dynamically determined by >>> another parameter. ?(You could implement this yourself inside of the >>> function, but why not make it easy.) >>> >>> The third step is that if a template expansion is *exactly* a variable >>> expansion, we get that value inserted as is (instead of stringified). >>> So: >>> >>> ?{ >>> ? ?foo => { >>> ? ? ?this => 'that', >>> ? ?}, >>> ? ?bar => '[% foo %]', >>> ?} >>> >>> should expand to: >>> >>> ?{ >>> ? ?foo => { >>> ? ? ?this => 'that', >>> ? ?}, >>> ? ?bar => { >>> ? ? ?this => 'that', >>> ? ?}, >>> ?} >>> >>> Combined with the second step, this would allow us to pass real data >>> structures to function calls inside of hash values that we are >>> expanding. >>> >>> And while we're at it, we can always allow an easier quoted string >>> syntax. ?So for instance no expansion would happen if you started the >>> string with %%. ?So: >>> >>> ?{ >>> ? ?foo => '%%[% Hello %]', >>> ?} >>> >>> would expand to: >>> >>> ?{ >>> ? ?foo => '[% Hello %]', >>> ?} >>> >>> Now if you squint right, the ability to call functions looks like Lisp >>> macros. ?The ability to suppress template expansion before the call, >>> then have it happen inside of the function gives us an equivalent to >>> Lisp macros. ?And we can implement the special forms directly in Perl >>> functions. >>> >>> Any template expansion system that gives you something with a >>> recognizable parallel to Lisp (albeit with a different syntax) >>> qualifies in my books as "sufficiently powerful" for any reasonable >>> need... >>> >>> Does anyone have any reaction other than, "He just went off the deep end"? >> _______________________________________________ >> Losangeles-pm mailing list >> Losangeles-pm at pm.org >> http://mail.pm.org/mailman/listinfo/losangeles-pm >> > _______________________________________________ > Losangeles-pm mailing list > Losangeles-pm at pm.org > http://mail.pm.org/mailman/listinfo/losangeles-pm From granny+lapm at gmail.com Tue Jun 26 20:22:46 2012 From: granny+lapm at gmail.com (Andrew Grangaard) Date: Tue, 26 Jun 2012 20:22:46 -0700 Subject: [LA.pm] next meeting: July 25, 2012 Message-ID: My Beloved Perlers! A quick save the date: our next meeting in Wed July 25, 2012. Start planning your vacations now :) Suggestions for presentation topics and or presenters? I'll try and bring back something from OSCON, and maybe finish my yapc CDD[1] project[2] RSVP appreciated by email or facebook[3] See you on the -1th wednesday in July. 1: CDD -- conference driven design 2: STILL A SECRET --> App::PM::Website 3: facebook event: http://www.facebook.com/events/397191746994118/