develooper Front page | perl.perl5.porters | Postings from March 2001

Overloadable lvalue operators and more

Thread Next
From:
Simon Cozens
Date:
March 19, 2001 07:51
Subject:
Overloadable lvalue operators and more
Message ID:
20010319153029.A27488@netthink.co.uk
I've been looking again at the idea of

    $foo.$bar = $baz

which makes sense if $foo is overloaded and the overloading sub returns an
lvalue.

It also lets you do "use overload '.' => sub :lvalue { $_[0]->{$_[1]}}" and
say

    $foo.attribute = $value

To do this, however, requires you to move "can't modify ..." checking from
compile time to run time. The following patch should NOT be applied to
bleadperl just yet, but it's from my experimental lab and just allows people
to play around with this. 

By moving the checking to run time, lvalue overloading magically starts
working. Lvalue functions returning array and hash slices magically start
working as well. See how easy it is.

However, it's incomplete because it allows non-overloadable operators to take
an lvalue. Currently, "-s $filename = 0" won't cause an error, nor will it
truncate the file to zero length. Guess which way I want to fix it. :)

==== //depot/sperl/op.c#1 - /home/simon/patchbay/sperl/op.c ====
@@ -1506,7 +1506,8 @@
       nomod:
 	/* grep, foreach, subcalls, refgen */
 	if (type == OP_GREPSTART || type == OP_ENTERSUB || type == OP_REFGEN)
-	    break;
+	    goto donemod;
+    /*
 	yyerror(Perl_form(aTHX_ "Can't modify %s in %s",
 		     (o->op_type == OP_NULL && (o->op_flags & OPf_SPECIAL)
 		      ? "do block"
@@ -1514,6 +1515,8 @@
 			? "non-lvalue subroutine call"
 			: PL_op_desc[o->op_type])),
 		     type ? PL_op_desc[type] : "local"));
+    */
+        o->op_flags |= OPf_MOD;
 	return o;
 
     case OP_PREINC:
@@ -1674,6 +1677,7 @@
     if (type != OP_LEAVESUBLV)
         o->op_flags |= OPf_MOD;
 
+donemod:
     if (type == OP_AASSIGN || type == OP_SASSIGN)
 	o->op_flags |= OPf_SPECIAL|OPf_REF;
     else if (!type) {
==== //depot/sperl/pp.h#1 - /home/simon/patchbay/sperl/pp.h ====
@@ -320,6 +320,9 @@
 	       SPAGAIN;	\
 	       (void)POPs; set(tmpsv); RETURN; } \
 	  } \
+        else if (PL_op->op_flags & OPf_MOD)   \
+            Perl_croak(aTHX_ "Can't modify non-overloaded %s",\
+                         PL_op_desc[PL_op->op_type]); \
 	} STMT_END
 
 #define tryAMAGICbin(meth,assign) tryAMAGICbinW(meth,assign,SETsv)

-- 
"Anyone attempting to generate random numbers by deterministic means is, of
course, living in a state of sin."
-- John Von Neumann

Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About