From: Neil W. <neilw@ActiveState.com> - 2002-06-18 10:14:29
|
Hi Keith, I just have to speak up on behalf of Perl syntax here. The following is all wrong: Keith Devens [18/06/02 05:30 -0400]: > This is actually very much > like how Perl handles barewords. If you have a hash and want to use a > bareword as a key, in the vast majority of cases it's no problem: > > $hash{shifty} = "eyes". > > But the moment you want to say > > $hash{shift} = "down" > > You have a problem because shift has special meaning in Perl. So, this > brings me to the last of our considerations: forward compatibility. Defined > this way, YAML will have about the same forward compatibility problems that > programming languages have. Putting aside the reality of Perl 6, if a new > version of Perl were to define a new function that people had used as hash > keys, it'd break existing code. That's why you're not supposed to use bare > words, but Perl will let you, knowing full well that it reserves the right > to break it later. It's a sort of "cultural mandate", in a way. Perl *always* interprets a literal /-?\w+/ as a string inside "stringifying" contexts. Two such contexts are hash keys and the LHS of "fat arrows": %hash = ( shift => 27, dump => 42, int => 21, push => "hello", # quotes required on RHS using 'strict'. -pop => "looks like an option", ); shift if $hash{shift}; pop if $hash{-pop}; If you really want to use the return value of a function inside a hash key, you have to make it look like an expression so Perl will evaluate it. That's really easy in practice: die "Foo!" unless $hash{ shift }; # die "Foo!" unless $hash{shift()}; # die "Foo!" unless $hash{ print("Hello"), $a + 1 } Where your point is valid is for the following: my $a = seven; print $a; If you just run that on the commandline (perl -le '$a=seven;print$a') you'll see that $a gets the *string* "seven". That's because it's a "bareword" which is turned into a string because no such function 'seven' exists at compile time. In fact, even this example will still print "seven": my $a = seven; print $a; sub seven { 7 } because the compiler didn't see the subroutine until after it compiled the opcode for the assignment. It all changes as soon as you start defining things at compile time. That's because Perl's compiler consults the symbol table whenever it finds a bareword, to DWYM. This prints "7": sub seven { 7 } $a = seven; print $a; This is the compile error you're after: use strict; my $a = seven; print $a; sub seven { 7 } Because no such function exists, and "strict" forbids the compiler to make a string out of it. So you're SOL. (I had to add "my" to declare $a, too). This fixes everything up again: use strict; sub seven { 7 } my $a = seven; print $a; Only a very specific class of barewords have ever been broken, and that's not even on by default. I'm not aware of any mode you can set which overrides stringification inside hash keys and fat arrows. I can only assume you were led astray by an editor's highlighting mode, and never actually tried any of this...? > In YAML > terms, as well as in Perl terms, the rule would be (YAML) and is (Perl): > "you should use quotes, but you don't have to. However, be careful, because > it'll break if we define a new type (or meta-character, I guess) (YAML) or > function (Perl)." This sucks the big one. I want guarantees that no data serialized under YAML:1.0 will break *ever*. Except perhaps in YAML:2.0, which might conceivably be totally different. My point is, I want the freedom to add an arbitrary number of metacharacters without worry. This all hinges on the assumption that we'll continue to use metacharacters to denote implicit types. If we don't, fine. I still want to be restrictive enough that later specifications simply use more metacharacters, thus allowing more things to be legal YAML, but still preserving the exact semantics of every previous version. To some extent, this is an orthogonal issue to DWIMity. I still want YAML to DWIM -- but I also want the next version of YAML to DWIMT (do what I mean tomorrow). I think we're pretty close to a solution that does that. In fact, I think most of the proposals out there come very close... with the sole exception of the "treat everything that's *not* recognized as a string" proposal, which has absolutely no forward compatibility beyond quoted strings. I cannot stress enough how much it sucks. I simply guarantee I will not use YAML unless I know that YAML I ship to my customers will be readable after I upgrade my application to the next version of libyaml. That's that! Later, Neil |