Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

Re: When to use Tie

by tilly (Archbishop)
on Jan 30, 2004 at 01:31 UTC ( [id://325103]=note: print w/replies, xml ) Need Help??


in reply to When to use Tie

My often stated opinion on tie is that it is a hack for a self-inflicted wound.

The self-inflicted wound is that Perl makes an iron distinction between how you manipulate its native data types (scalars, arrays, hashes, filehandles, etc), and how you address user-created data types. From the syntax you can tell whether you have a native data type or a user-created data type. The hack is that Perl offers a wrapper to create something that looks like a native data type from a user-created data type. The hack has several drawbacks, however:

  1. It can add bugs. With different releases, the bugs move and overall seem to be getting better. But there remain places where tied objects don't quite do what they should. The reason for this is that tie is implemented by putting if checks in every operation that you might do with a Perl "thing". There are a lot of operations, and it is easy to miss something. Grabbing a random one, you couldn't untie a scalar within a tied FETCH until recently.
  2. It is not extensible. Well, it is if you are willing to tell people that they have to write tied(%foo)->bar("baz") to get at your extensions. But people tend to balk at that. So in practice tie only really works smoothly if the datatype that you are creating corresponds exactly to a native datatype.
  3. It is slow. I'm not just talking of the performance penalty for accessing a tied object. I'm also talking of the performance penalty for having every operation with native data types have to stop and check whether you are tied or not. If Perl lost tie, it would speed up most code by a reasonable margin.
This is something that I clearly realized after I learned some Ruby. Unlike Perl, in Ruby everything is an object. Including native datatypes. Which means that the equivalent of tie doesn't even have to be written in Ruby, it is part of the language! (Well, actually the appropriate mix-ins needed to be written to make it easy to emulate native datatypes. But no core change was needed.) And the equivalent of a tied object lacks all of the drawbacks listed above.

Of course the drawback for the way that Ruby does it is that you cannot syntactically tell what anything is. Therefore Ruby cannot auto-coerce as liberally as Perl, and cannot auto-vivify things.

With all that said, what is my advice on tie? I'd say that people should use tie when Perl's syntactic design choices are getting in your way. If, however, you have reason to offer something that is a Perl datatype + more, then I'd bite the bullet and make it a real object.

Replies are listed 'Best First'.
Re: Re: When to use Tie
by ysth (Canon) on Jan 30, 2004 at 08:52 UTC
    But tie isn't the only kind of magic there is, and all magic (except overload) is triggered by the same code checks. Most of the variables listed in perlvar use some form of magic (admittedly, a few do so uselessly; for example $^O).

    I thought untie within a FETCH used to work and got broken at some point along the way and then fixed. This is an area of valid complaint: magic really isn't well represented in perl's regression tests.

    Speaking of pervasive performance penalties, perl has an "optimization" of not reference counting items on the stack (including parameters in @_ in most cases). To keep things from getting garbage collected while still on the stack, it has tons of special code to mark things that should be kept even with a refcount of 0, and special code when dealing with arrays to check if the array at hand is @_ without refcounts. I've often wondered what the gain or loss would be if that mechanism were ripped out and regular reference counting were used for the stack, but its really to late now; there'd be too much work and too much danger of introducing bugs.

Re: Re: When to use Tie
by hardburn (Abbot) on Jan 30, 2004 at 14:17 UTC

    My gripe with tie in the OP was more of a issue of theory. I specifically avoided implementation issues (like speed).

    To me, tie represents the ultimate in encapsulation. In theory, it is completely transparent after you've called tie (though as you mention, there are places where it's not transparent--these places should be considered bugs). It grates on me to see people treating tied hash lookups as if they were method calls, because you're willfully ignoring the reason for tie's existance. Speed is also a concern, but it would still annoy me even if it wasn't a factor.

    A short tangent on Ruby: I haven't learned a lot of this language, but what little I studied teached me a few things. I used to wonder why the Java people were in such a huff over integers not being objects. Why would you want to extend the behavior of an integer? Ruby showed me why: it's so you can call operations directly on the datatype, and thus (as you noted) eliminates the need for tie.

    ----
    I wanted to explore how Perl's closures can be manipulated, and ended up creating an object system by accident.
    -- Schemer

    : () { :|:& };:

    Note: All code is untested, unless otherwise stated

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://325103]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others about the Monastery: (4)
As of 2024-04-20 00:37 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found