blueflashlight has asked for the wisdom of the Perl Monks concerning the following question:

Hi, Monks ...

I've tried my brains out to understand tying variables (read perltie, all the tie manpages, the tie tutorial here; I even opened my Conway book, all to no avail.)

What I want to do is to tie the scalar variable "$tie" to the output of localtime(), so that each time I use $tie, I get the current time.

It's silly to even include my pathetic attempt, but ...
#!/usr/bin/perl -w use strict; use Tie::Scalar; use vars qw($now); tie ($now, localtime()); print "$now\n"; sleep 5; print "$now\n";

... which results in ...
Can't locate object method "TIESCALAR" via package "Mon Sep 24 21:29:5 +0 2001" at tienow.pl line 7.

I'm sure I'd know how to do this if I understood the first thing about OO programming, but I find that to be another opaque subject. Perhaps I'll ask about that later, but could someone explain how to do what I want to do, or at least push me further in the right direction, please?

Thanks ... --blueflashlight

Replies are listed 'Best First'.
Re: Tying
by merlyn (Sage) on Sep 25, 2001 at 08:50 UTC
    untested, but I think I'll get this right. :)
    { package Tie_timer; sub TIESCALAR { bless {}, shift } sub FETCH { scalar localtime } } tie $now, Tie_timer; print $now;

    -- Randal L. Schwartz, Perl hacker

      you are my hero.

      Taking your example, and my pathetic perl ability, I came up with:
      #!/usr/bin/perl -w use strict; use Tie::Scalar; package Tie_timer; sub TIESCALAR { bless {}, shift } sub FETCH { scalar localtime } package main; my $now; tie ($now, "Tie_timer"); print "$now\n"; sleep 5; print "$now\n"

      ... which worked perfectly. Perhaps I even understand it better.

      thanks again. --sandy

        It's a small thing, but you don't actually need to use Tie::Scalar. You're not using anything from it.

        --
        <http://www.dave.org.uk>

        "The first rule of Perl club is you don't talk about Perl club."

Re: Tying
by dragonchild (Archbishop) on Sep 25, 2001 at 15:44 UTC
    A more generic approach would be to put the package in its own module. Maybe have a file called Tie/Timer.pm and have it contain:
    package Tie::Timer; sub TIESCALAR { bless {}, shift; } sub FETCH { scalar localtime } 1; __END__
    The reasons to do this are if you want to
    1. Use this in more than one script
    2. Expand its capabilities
    3. Create a Tie::Timer2 which inherits from this, but instead might do the array-form, not the scalar form.
    It's also a really neat way to start learning about OO.

    ------
    We are the carpenters and bricklayers of the Information Age.

    Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement.

      good idea; sorry if I sound dense, but what part of this would be the "start" of learning OO? If I put the package in it's own module, and use'd the module, is that OO programming in itself? Or would I have to use some of that "arrow notation" stuff to achieve "true OOness"?

      Thanks, --Sandy
        The 'arrow notation' is just dereferencing. Some variable is a reference (something like a pointer, if you're a C person) to another variable. We can pass that reference around like we pass any scalar around. So, instead of passing a huge hash to a function, we might pass a reference to that hash into the function instead, saving memory usage.

        Just putting a package in a module and use-ing it also isn't OO programming. That's modular programming, which is an excellent thing to do in any form of programming. By modularizing, you're factoring out often-used pieces of code, making it easier to manage, debug, maintain, upgrade, and re-use. Yes, reusability is a "hallmark" of OO programming, but it's not restricted to being something only OO can do.

        What is OO programming has less to do with how you write your code as how you think about your code. Some programmers were instinctively writing OO-like code back in the 50's, well before any OO languages were invented. (If you think about it, why would OO languages have been invented, save to facilitate what some programmers were already trying to do?)

        So, instead of OO programming, we should be talking about OO design. The big thing, for me, about OO design is thinking about your program as a series of act-ers, or agents. Each one knows about certain information and how to do certain things. They also have a number of ways they know how to talk, or interface. The only way anyone can get them to do anything (including giving knowledge of their information) is by using this interface.

        How is tie-ing related to OO? Well, you have some class, or specification of what the object can and cannot do. That is Tie::Scalar, in your example. You have an interface, which would be creating it and asking for its value. (Actually, the interface to Tie::* is any action you can do on that type of variable, which only strengthens my argument that Perl variables are objects.) You have a way of defining that interface, and you can create many "objects" of that type, or class.

        From a layman's point of view, that sounds relatively close to OO to me. (Yes, I'm avoiding the technical definitions, because they don't seem necessary right now.)

        ------
        We are the carpenters and bricklayers of the Information Age.

        Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement.