4 ms·
This is how it works: BEGIN { # an execution block that runs when the module is compiled *f = # assigns to the symbol "f" inside the symbol table ... (lo
by G3rn0ti 5y ago
This is how it works:
BEGIN { # an execution block that runs when the module is compiled
*f = # assigns to the symbol "f" inside the symbol table ...
(localtime->wdayname eq 'Fri') # is it Friday?
? sub() {} # ... on friday an anonymous subroutine taking no arguments
: sub {}; # ... on every other day a subrouting taking arguments
} # closes the execution block
# The following line executes the subroutine "f" and divides the result by 1 on fridays
# but on other days causes the interpreter to trigger a syntax error because it expects
# f to take an argument list "(...)" but receives an operator "/".
f/1;#/+
- metalliqaz 5y agoThank you for this. I hate trying to read Perl so much. What is the "#/+" for?
- jwilk 5y agoOn Fridays, it's just a comment. Otherwise, "f/1;#/+" is equivalent to something like: f(/1;#/ +) where /1;#/ is a regexp matching operator, and stray + triggers syntax error.
- space_ghost 5y agoFlavor? "#" starts a comment, so the "/+" characters are ignored by the interpreter.
- deleted 5y ago[deleted]
- G3rn0ti 5y ago> What is the "#/+" for? I am sure this is not necessary for the behavior described. It's just a comment. BTW: I am working for a company still maintaining a large Perl code base and I think this is rather obscure stuff. You rarely need to run something at compile time, hack the symbol table and you almost never need "sub() {}" to define subroutines with an empty "prototype". If I saw this in a code review I would most definitely had a closer look and would decline a PR if that was unnecessary. Meta programming should not be done lightheartedly and better serves a serious purpose.
- mmaunder 5y agoWorked as a Perl dev for 15 years and enjoyed it. The hardest thing was the number of ways to do OO Perl using Perl5. Everyone has their own flavor. And TMTOWTDI was a motto the community was proud of. Having said that, nothing could touch mod_perl performance under Apache in the late 90s. Massive web apps were built on this including eToys dot com where I worked before it imploded in the dot-com bust.
- cutler 5y agoMoose, Mouse, Moo, Mo ... bah! Just give me The Damian's simple blessed hashref.
- tomc1985 5y ago> Worked as a Perl dev for 15 years and enjoyed it. The hardest thing was the number of ways to do OO Perl using Perl5. Everyone has their own flavor. And TMTOWTDI was a motto the community was proud of. One of my frist dev jobs was slinging perl script, I loved that attitude and it made for a fantastic learning environment. I really dislike the feeling of having to write code in a straightjacket because tHe TeAm CaN't UnDeRsTaNd iT!!! We minimized the negatives of TMTOWTDI by incorporating a house style, but it was flexible because we were all smart people whose minds didn't crash because we saw a statement we didn't expect.
- programd 5y ago> Worked as a Perl dev for 15 years and enjoyed it Similar situation here. Perl is awsome and I'm still bitter that Python won. I mean significant whitespace - what great madness is this??? Anyway, yes, mod_perl ran the Web for about a decade in the early 2000s and I built and maintained huge websites which were all Perl on the back end. BTW the book "Perl Best Practices" by Damian Conway [0] is the best general programming book I have ever read. Every software engineer should read it no matter what language they program in. So much good advice which applies to pretty much any significant software project. IMHO right up there with the "Mythical Man Month", though obviously much more low level. [0] https://www.oreilly.com/library/view/perl-best-practices/0596001738/ https://www.oreilly.com/library/view/perl-best-practices/059...
- darrenf 5y ago> # The following line executes the subroutine "f" and divides the result by 1 on fridays > # but on other days causes the interpreter to trigger a syntax error You have this the opposite way round to what's happening (and the description). It only compiles on a Friday, i.e. when the sub takes no arguments. Removing all the "only on a Friday" stuff boils down to the difference between these two: # this compiles sub f() {} f/1;#/+ # this doesn't compile sub f {} f/1;#/+ NB. the latter does compile if you take the `+` off the end, when it parses to (using -MO=Deparse) sub f {} f /1;#/; When the sub is declared with zero args, `f` can only compile to mean "call f with no args", thus `/1;#+` means "divide the return value by one, end statement, rest is a comment". However, when the sub does accept args, `f <stuff>` tries to compile `<stuff>` into arguments to send - and it's a regex pattern `/.../` so the # isn't a comment, it's part of the regex, and the + is where modifiers go - but it's invalid, and is the syntax error. A valid pattern modifier would also compile, e.g.: sub f {} f/1;#/m The argument to `f` here is "whether the pattern /1;#/ matched against $_": use feature 'say'; sub f { shift ? "matched" : "unmatched" } $_ = 'this matches 1;#'; say f /1;#/; $_ = 'this does not match'; say f /1;#/; Which prints: matched unmatched So, it turns out the + needn't be characterised as an invalid modifier after all - it's just addition with a missing second operand. Add one in and it works as you'd expect: use feature 'say'; sub f { int shift } $_='1;#'; say f/1;#/+1 # prints 2
- Sophira 5y ago> You have this the opposite way round to what's happening (and the description). It only compiles on a Friday, i.e. when the sub takes no arguments. Isn't that what the parent said, going by your quote? They said "the following line [...] on fridays but on other days causes the interpreter to trigger a syntax error".
- darrenf 5y agoYes! You're right. Not sure what happened to my brain there. Too much staring at Perl, I suspect.
- Sophira 5y agoThis is generally correct, but your final analysis is slightly wrong and this is a perfect example of why Perl can be difficult to parse. If you add a 1 to the end of the "f/1;#/+" line, so that it becomes "f/1;#/+1", the code will become correct. What's actually happening is that on Fridays, the "f/1;#/+" line means "call f, divide the result by 1, and throw away the result", followed by a comment. On any other day, it means "call f with the regex parameter /1;#/ and add an unspecified parameter to it". Since the right hand side of the + operator isn't specified, it is syntactically incorrect.
- hnu0847 5y agoWhy does the following expect arguments: : sub {}; Don't all perl subroutines allow any number of arguments (including 0) to be passed? Does the fact that the above is an anonymous subroutine affect the answer to my question?
- jwilk 5y agoA sub without prototype (anonymous or not) indeed allows any number of arguments. That's sufficient to trigger the syntax error.
- hnu0847 5y agoSo basically this: sub() {} does not try to parse the /1;#/+ as an argument because the () indicates there are no arguments (although they could be explicitly included if f were called with (), whereas this: sub f {} does try to parse the /1;#/+ as an argument because that's perl's behavior if () are omitted?
- jwilk 5y agoThat's right.