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

magic

Thread Next
From:
Hugo
Date:
March 16, 2000 19:42
Subject:
magic
Message ID:
200003170348.DAA31327@crypt.compulink.co.uk
[The suggestions here are not intended for 5.6.0, but I wanted to write
them down while they were fresh on my soul.]

I've spent the last couple of days trying to implement a tied variable
using U magic. After looking at Nick's comments near Tk's use of a
similar approach (thanks Nick!), I wonder if there is a reason that
user-definable magics ('U', '~') of the same type should not
automatically chain. It would make the Tk code, and my own, rather
simpler, and it seems a more reasonable default than the current
(in which sv_magic simply ignores the new request if there is already
magic of the same type attached).

The ufuncs structure specifying the magic also has an index you can
use to distinguish one magic from another. Tk uses here the address
of some context object (AIUI), and I have done something similar.
I'd like to suggest a recommendation in the docs that this index
always be set to the address of some memory specific to your code -
something you've malloced, or perhaps the address of a function -
that you expect to own for the lifetime of the magic, so that you
can be sure to disambiguate not only between separate instances of
your own magic, but also between your magic and someone else's of
the same type, attached to the same SV. (My original inclination
was to use a numeric 0, 1, 2... index until I understood Nick's
code better.)

If there is some consensus that these changes would be desirable
I'll submit a patch for them.

Independently of that, I'd also like to suggest a new form of
user-defined magic - probably 'X' - that would use the XS calling
convention rather than the C calling convention to access the
set/get routines. I want to use an XS routine since I don't know
what type the variables are, and I'd rather let xsubpp do the work
of applying its knowledge of such things than start copying
substantial parts of its code. My current solution uses 5 routines
for the tie - one to tie the magic to the variable, a get/set pair
in the .xs file preamble, which push the arguments on the stack,
and a get/set pair as XS routines which do the actual work.

Again, if this addition would be desired I'll happily submit a patch.

All "you don't need to do that - here's a far easier way" gratefully
welcomed.

Hugo
---
/* all untested; there's got to be an easier way */
I32
_get_thisvar(IV index, SV *sv) {
    dSP;
    PUSHMARK(SP);
    XPUSHs(sv);
    PUTBACK;
    (void)call_pv("Class::_get_thisvar", G_DISCARD);
    return (I32)0;
}

I32
_set_thisvar(IV index, SV *sv) {
    dSP;
    PUSHMARK(SP);
    XPUSHs(sv);
    PUTBACK;
    (void)call_pv("Class::_set_thisvar", G_DISCARD);
    return (I32)0;
}

MODULE = Class		PACKAGE = Class		

void
_tievar_thisvar(sv)
	SV* sv
    PREINIT:
	struct ufuncs uf;
    CODE:
	uf.uf_val = &_get_thisvar;
	uf.uf_set = &_set_thisvar;
	uf.uf_index = (IV)&_get_thisvar;
	/* need to add Nick's code to allow multiple U-magics */
	sv_magic(sv, 0, 'U', (char*)&uf, sizeof(uf));

I32
_get_thisvar(THIS)
	char * THIS
    CODE:
	THIS = thisvar;
	RETVAL = 0;
    OUTPUT:
	RETVAL
	SETMAGIC: DISABLE
	THIS

I32
_set_thisvar(THIS)
	char * THIS
    CODE:
	thisvar = THIS;
	RETVAL = 0;
    OUTPUT:
	RETVAL


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