Pro tip: add test cases to your CI runs with modified system date.
The thing is, you need to have a pretty corkscrew mind to think about cases like this. What date to change to? Far into the future? Far into the past? To a weekend? To a DST change? To Friday the 13th? To a US holiday? To a Muslim, Jewish, Chinese, Soviet, Albanian holiday? To a particular weekday? To Hitler's birthday? What if it's Lenin's? To that one day my coworker was depressed because the boss denied him a rais…
Perl code that is syntactically correct only on Fridays
71–80 of 233 posts
Re: Perl code that is syntactically correct only on Fridays
#72This 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 div…
> # 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 ` tries to compile `` 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 2Re: Perl code that is syntactically correct only on Fridays
#73Re: Perl code that is syntactically correct only on Fridays
#74The code is never syntactically correct however the syntax error is not identified by the Perl interpreter on Fridays.
Re: Perl code that is syntactically correct only on Fridays
#75Is the proof, that perl is capable of this behaviour?! I don't get it - what is the point?
I read all the comments and still don't get it. What am i missing?
Re: Perl code that is syntactically correct only on Fridays
#76Earlier quoted context omitted.
Personally I really don't like code that deals with time - it's too easy to place a "get time stamp" call anywhere in code. If it's down in the bowels of some piece of functionality trying to test it becomes a headache.
This is one of those pieces of software engineering wisdom that only comes from experience. Try explaining to a newish dev why they shouldn't `const now = Date.now()` or whatever anywhere they want, but rather do it in one place for the lifecycle and pass it around, and they will look at you funny and think it's a waste of time. Classic case of simple vs easy. Time has the potential to complect everything it touches.
Re: Perl code that is syntactically correct only on Fridays
#77Earlier quoted context omitted.
Right, the beauty of this is that it's a syntax error he's produced. Sure any language can write code to produce a runtime error under any condition at all. And a lot of languages have features that allow them to run code at compile time, and similarly produce errors then too. But those languages don't allow you to ruin the syntax of the language. I guess it's something that requires macros. Would it be safe to say t…
It is formally proven that Perl can't be parsed! https://www.perlmonks.org/index.pl?node_id=663393
The real Perl parser disambiguates with heuristics and run-time hints.
There exists an unambiguous subset of Perl syntax that is expressible with a BNF grammar, and such is amenable to all parsers. http://p3rl.org/standard#DESCRIPTION
Re: Perl code that is syntactically correct only on Fridays
#78I don't get it! It is clearly written in the code, that the progam should behave this way. Is the proof, that perl is capable of this behaviour?! I don't get it - what is the point? I read all the comments and still don't get it. What am i missing?
Re: Perl code that is syntactically correct only on Fridays
#79In similar vein: parsing C++ is literally undecidable: https://blog.reverberate.org/2013/08/parsing-c-is-literally-... You can't even decide if a particular "*" is multiplication or a pointer dereference until you resolve templates, which is Turing-complete.
Unless something has changed a lot, C++ templates at least only used to be Turing complete if you assume you're allowed unlimited recursive template applications, and compilers were free to restrict that (and did). Has that changed? In theory I agree with you that this is horribly ugly - I very much prefer simple grammars (the irony being my favourite language to use is Ruby, which has an atrocious grammar). In pract…
Re: Perl code that is syntactically correct only on Fridays
#80Earlier quoted context omitted.
Most other languages would require `eval` and having incorrect code as syntactically correct string literal. But because Perl is parsed as it is executed, incorrect code raises syntax error only when it is reached by execution.
Right, the beauty of this is that it's a syntax error he's produced. Sure any language can write code to produce a runtime error under any condition at all. And a lot of languages have features that allow them to run code at compile time, and similarly produce errors then too. But those languages don't allow you to ruin the syntax of the language. I guess it's something that requires macros. Would it be safe to say t…
the following code produces a syntax error if the time is less than 10 seconds after a full minute.
#define T __TIME__
#if T[6]-48
#define X 1
#else
#define X /
#endif
void main()
{
write("%d, %c, %O\n", X, T[6], T);
}