develooper Front page | perl.perl5.porters | Postings from June 2010

methods and bareword file handles, action at a distance, (un)speed

Thread Next
From:
Nicholas Clark
Date:
June 14, 2010 00:57
Subject:
methods and bareword file handles, action at a distance, (un)speed
Message ID:
20100614075727.GE17934@plum.flirble.org
On Mon, Jun 14, 2010 at 09:45:58AM +0200, Nicholas Clark wrote:

> - Log -----------------------------------------------------------------
> commit 086d291379a28ceb3cd7cc6416747be8c426476b
> Author: Nicholas Clark <nick@ccl4.org>
> Date:   Mon Jun 14 09:44:49 2010 +0200
> 
>     Note why pp_tie can't use call_method() for a package name.
>     
>     Plus a test that would fail if it did.
> -----------------------------------------------------------------------
> 
> Summary of changes:
>  pp_sys.c   |    6 ++++--
>  t/op/tie.t |    8 ++++++++
>  2 files changed, 12 insertions(+), 2 deletions(-)

Because, if you did this:

diff --git a/pp_sys.c b/pp_sys.c
index 1dadea8..7ec88e0 100644
--- a/pp_sys.c
+++ b/pp_sys.c
@@ -844,7 +844,8 @@ PP(pp_tie)
 	    break;
     }
     items = SP - MARK++;
-    if (sv_isobject(*MARK)) { /* Calls GET magic. */
+    {
+	SvGETMAGIC(*MARK);
 	ENTER_with_name("call_TIE");
 	PUSHSTACKi(PERLSI_MAGIC);
 	PUSHMARK(SP);
@@ -854,26 +855,6 @@ PP(pp_tie)
 	PUTBACK;
 	call_method(methname, G_SCALAR);
     }
-    else {
-	/* Not clear why we don't call call_method here too.
-	 * perhaps to get different error message ?
-	 */
-	STRLEN len;
-	const char *name = SvPV_nomg_const(*MARK, len);
-	stash = gv_stashpvn(name, len, 0);
-	if (!stash || !(gv = gv_fetchmethod(stash, methname))) {
-	    DIE(aTHX_ "Can't locate object method \"%s\" via package \"%"SVf"\"",
-		 methname, SVfARG(SvOK(*MARK) ? *MARK : &PL_sv_no));
-	}
-	ENTER_with_name("call_TIE");
-	PUSHSTACKi(PERLSI_MAGIC);
-	PUSHMARK(SP);
-	EXTEND(SP,(I32)items);
-	while (items--)
-	    PUSHs(*MARK++);
-	PUTBACK;
-	call_sv(MUTABLE_SV(GvCV(gv)), G_SCALAR);
-    }
     SPAGAIN;
 
     sv = TOPs;

instead of

$ ./perl -e 'tie @a, "FOO"'
Can't locate object method "TIEARRAY" via package "FOO" (perhaps you forgot to load "FOO"?) at -e line 1.

you would get:

$ ./perl -e 'fileno FOO; tie @a, "FOO"'
Can't locate object method "TIEARRAY" via package "IO::File" at -e line 1.


Cool? Not. :-)


Which reminded me what Artur said years ago - as well as action at a distance,
there's a speed hit on every class method call because first the code does a
stash lookup to see if the package name string is actually a filehandle:

    http://perl5.git.perl.org/perl.git/blame/086d2913:/pp_hot.c#l3108

So I wondered. Should we add a flag to pp_method and pp_methodnamed, to allow
that lookup to be disabled, and add a lexical pragma to enable disabling.
[And a better way to describe that :-)]

I've not tried to benchmark this, so I don't know what the gain might be.

Nicholas Clark

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