in reply to Re^6: odd line in windows
in thread odd line in windows

yet it's not what I naively expected.

I have similar reservations about the Object Oriented Inline example in the cookbook:

SV* new(char* class, char* name, char* rank, long serial) { Soldier* soldier; SV* obj_ref = newSViv(0); SV* obj = newSVrv(obj_ref, class); New(42, soldier, 1, Soldier); soldier->name = savepv(name); soldier->rank = savepv(rank); soldier->serial = serial; sv_setiv(obj, (IV)soldier); SvREADONLY_on(obj); return obj_ref; }

obj_ref is an IV (set to 0), pointed at by obj which is an RV, who's IV is set to the address of the struct and then set read only. But then it is obj_ref that is returned.

Then again, I find almost nothing about XS intuitive and the documentation is shite. If you ask questions about it you either get no answers or an answer of "Do this", with no explanation of why that works. And that smacks of the passing on of rote learnt knowledge with no true understanding. If there is anyone left who really understands this stuff, they are keeping that knowledge firmly to themselves.

If I could get help in understanding this stuff I might have published a whole lot more of my half-finished, but dead-in-the-water projects.


Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.

Replies are listed 'Best First'.
Re^8: odd line in windows
by syphilis (Archbishop) on Sep 08, 2011 at 13:24 UTC
    I have similar reservations about the Object Oriented Inline example in the cookbook

    I can't help much with those questions - your line about "rote learnt knowledge with no true understanding" pretty much sums me up (except that I don't have much of the "rote learnt knowledge" :-)

    I *do* hope the basic construct being demonstrated in that cookbook example is not doing anything too dastardly, as it's one that I've been using extensively, and for quite a long time (in, eg, all of my Math::* modules). I've found it to be very serviceable and reliable - which hopefully stands it in good stead.

    Cheers,
    Rob
      I can't help much with those questions

      But do the questions make sense to you? That is, do you see the same anomalies?


      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.
        But do the questions make sense to you?

        Certainly - and I've often wondered, in passing, precisely what is going on there.
        But I haven't ever gone to the extent of really trying to get to grips with it. (Gee, if I took the time to ponder everything I don't understand I'd lead a very troubled existence, indeed ;-)

        Anyway, I'm glad you asked about it ... and even gladder that ikegami came up with some answers.

        I'll look at modifying the "Discussion" of this code in the Cookbook, to explain some of what ikegami uncovered.
        There's actually a bug in that "Discussion", anyway. It still mentions using strdup, which was replaced long ago by savepv.

        Cheers,
        Rob
Re^8: odd line in windows (names, XS)
by tye (Sage) on Sep 08, 2011 at 16:51 UTC

    Looks like if you just swap the two variables names (just in the declaration lines), then it makes sense.

    Firing up Acme::ESP, I suspect the author was thinking of the IV as an opaque thing that refers to the real object ("Soldier") and the RV was the Perl (proxy) object. So he called the IV "obj_ref" and the Perl object "obj" but then, when writing the rest of the code, he naturally used "obj_ref" to get the Perl reference and "obj" to get what would result from de-ref-ing "obj_ref".

    So, if you have two different things that are "objects" and one refers to the other and one is also a Perl reference, then "obj" and "ref" are way too ambiguous to be enough to get good variable names.

    SV* new( char* class, char* name, char* rank, long serial ) { Soldier* soldier; SV* addr; SV* perlObj; New( 42, soldier, 1, Soldier ); soldier->name = savepv(name); soldier->rank = savepv(rank); soldier->serial = serial; addr = newSViv( (IV)soldier ); SvREADONLY_on( addr ); perlObj = newSVrv( addr, class ); return perlObj; }

    But I'd avoid most of the "writing Perl code in C" of such an XS example and instead have the XS functions provide a C-like interface and use Perl wrappers to do the Perl stuff. You'll end up with more flexible code with fewer bugs that way, IME.

    IV new( char* class, char* name, char* rank, long serial ) { Soldier* soldier; New( 42, soldier, 1, Soldier ); soldier->name = savepv(name); soldier->rank = savepv(rank); soldier->serial = serial; return (IV)soldier; }

    - tye        

      if you just swap the two variables names (just in the declaration lines), then it makes sense.

      Yes. That makes more sense. And your re-write more so. Thanks.


      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.
Re^8: odd line in windows
by ikegami (Patriarch) on Sep 08, 2011 at 20:00 UTC

    Update: This is wrong. should have looked at what newSVrv did.


      That's essentially the same thing tye said above.

      But, that still leaves the questions

      • How come it works as erroneously shown in the documentation?
      • What happens to all the code that has been written based upon that bad documentation, now that the IV and RV fields have been combined?

      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.

        I stand corrected. The code in the recipe is actually correct.

        SV* obj_ref = newSViv(0); SV* obj = newSVrv(obj_ref, class);

        newSVrv doesn't create a reference as a I had guessed, it returns a new SV and makes obj_ref a reference to it. WTF? How odd is that!!!

        So obj_ref holds a reference to the blessed scalar in obj, which in turn contains an integer which corresponds to the memory address of the C object.

        set_iv is not being used on the reference, so there are no issues wrt to recent changes in scalar types.

        Update: This is wrong. should have looked at what newSVrv did.