X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2Foverload.pm;h=dfcdb02b1e658130bbdbc9ff15541edae2aaa9ed;hb=b3ac6de7f0c7a63b73f1cf3ea9e371470f7d1cb0;hp=c9044db0dc5a8bc353081caa5376b62b03901c66;hpb=dde527fc6256d3b4a78a8a6187a9b8048cc76da5;p=p5sagit%2Fp5-mst-13.2.git diff --git a/lib/overload.pm b/lib/overload.pm index c9044db..dfcdb02 100644 --- a/lib/overload.pm +++ b/lib/overload.pm @@ -100,6 +100,32 @@ sub mycan { # Real can would leave stubs. return undef; } +%constants = ( + 'integer' => 0x1000, + 'float' => 0x2000, + 'binary' => 0x4000, + 'q' => 0x8000, + 'qr' => 0x10000, + ); + +sub constant { + # Arguments: what, sub + while (@_) { + $^H{$_[0]} = $_[1]; + $^H |= $constants{$_[0]} | 0x20000; + shift, shift; + } +} + +sub remove_constant { + # Arguments: what, sub + while (@_) { + delete $^H{$_[0]}; + $^H &= ~ $constants{$_[0]}; + shift, shift; + } +} + 1; __END__ @@ -522,6 +548,72 @@ Returns C or a reference to the method that implements C. =back +=head1 Overloading constants + +For some application Perl parser mangles constants too much. It is possible +to hook into this process via overload::constant() and overload::remove_constant() +functions. + +These functions take a hash as an argument. The recognized keys of this hash +are + +=over 8 + +=item integer + +to overload integer constants, + +=item float + +to overload floating point constants, + +=item binary + +to overload octal and hexadecimal constants, + +=item q + +to overload C-quoted strings, constant pieces of C- and C-quoted +strings and here-documents, + +=item qr + +to overload constant pieces of regular expressions. + +=back + +The corresponding values are references to functions which take three arguments: +the first one is the I string form of the constant, the second one +is how Perl interprets this constant, the third one is how the constant is used. +Note that the initial string form does not +contain string delimiters, and has backslashes in backslash-delimiter +combinations stripped (thus the value of delimiter is not relevant for +processing of this string). The return value of this function is how this +constant is going to be interpreted by Perl. The third argument is undefined +unless for overloaded C- and C- constants, it is C in single-quote +context (comes from strings, regular expressions, and single-quote HERE +documents), it is C for arguments of C/C operators, +it is C for right-hand side of C-operator, and it is C otherwise. + +Since an expression C<"ab$cd,,"> is just a shortcut for C<'ab' . $cd . ',,'>, +it is expected that overloaded constant strings are equipped with reasonable +overloaded catenation operator, otherwise absurd results will result. +Similarly, negative numbers are considered as negations of positive constants. + +Note that it is probably meaningless to call the functions overload::constant() +and overload::remove_constant() from anywhere but import() and unimport() methods. +From these methods they may be called as + + sub import { + shift; + return unless @_; + die "unknown import: @_" unless @_ == 1 and $_[0] eq ':constant'; + overload::constant integer => sub {Math::BigInt->new(shift)}; + } + +B Currently overloaded-ness of constants does not propagate +into C. + =head1 IMPLEMENTATION What follows is subject to change RSN. @@ -597,6 +689,8 @@ C is present (possibly undefined). This may create interesting effects if some package is not overloaded, but inherits from two overloaded packages. +Barewords are not covered by overloaded string constants. + This document is confusing. =cut