http://qs321.pair.com?node_id=199446


in reply to How might I return tied scalar that does not have to be dereferenced as $$scalar?

this isn't completely possible. no matter what you do with tie, bless, etc. the following lines won't work as you expect:
$d = "Nov 25, 1971"; print "\$d contains $d\n"; # "Nov 25, 1971" print "\$d as unixtime:", $d->to_unixtime, "\n";

with a tie, you can't directly do $d->to_unixtime, it has to be tied($d)->to_unixtime. otherwise you'll get the message: Can't locate object method "to_unixtime" via package "Nov 25, 1971" (perhaps you forgot to load "Nov 25, 1971"?)

with a regular object, you can't of course do $d = "Nov 25, 1971" because this would destroy the object previously assigned to $d.

the most functional hack I could come up with is the use of tie AND overload AND tye's suggestion, as in:

Datum->tieVar( (my $d), -type=>'date' ); $d = "Nov 25, 1971"; print STDOUT "\$d contains $d\n"; # "Nov 25, 1971" print STDOUT "\$d as unixtime:", $d->to_unixtime, "\n"; package Datum; use overload '""' => \&to_string; sub tieVar { my $class= shift @_; my $toTie= \$_[0]; shift @_; tie $$toTie, $class, @_; } sub TIESCALAR { my $class = shift; my $instance = shift || undef; return bless \$instance => $class; } sub STORE { ${$_[0]} = $_[1]; } sub FETCH { # this just returns "self" # (won't be good in some cases) return $_[0]; } sub to_string { # this is the "real" FETCH method return ${$_[0]}; } sub to_unixtime { return "foobar"; }
this prints what you expect:
$d contains Nov 25, 1971 $d as unixtime:foobar
...but this is a hack, as it works correctly only when fetching $d in a string context. it has the implicit advantage, however, that $d could return something different (perhaps $d->to_unixtime) in numeric context.

cheers,
Aldo

King of Laziness, Wizard of Impatience, Lord of Hubris

Replies are listed 'Best First'.
Re: Re: How might I return tied scalar that does not have to be dereferenced as $$scalar?
by rr (Sexton) on Sep 23, 2002 at 17:01 UTC
    Hello Aldo

    I guess that what I want to do is not possible without creating new basic variable types. This project is for an OSS database abstraction layer that I wrote that automatically scavenges the db for meta information, creates classes to represent rows in tables. Each class then uses a collection of the Datum instances. This Datum class does type checking based on it's SQL type in the DB, and formats things correctly. You can provide additional type checking by configuration file (like dbname.table.colum Datum's must be all CAPS).

    My purpose in posting was to find a way to make coding with these objects faster by getting rid of using methods to update/get the values of the Datum instances. Using the overload+tie kinks above give me most of what I need. Too bad you cannot overload the assignment operator.

    Again, thanks to all all for your input.

    rr