Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I call methods on a tied variable?

Tags:

object

perl

tie

I've just started to learn about tie. I have a class named Link which I would like to do the following thing:

  • if fetched, return the link's address
  • if stored, store the new address
  • be able to call methods on it

So far, my code is :


package Link;

sub FETCH {
    my $this = shift;
    return $this->{"site"};
}

sub STORE {
    my ($self,$site) = @_;
    $self->{"site"}   = $site;
}

sub print_method {
    my $self = shift;
    print $self->{"site"};
}

sub TIESCALAR {
    my $class = shift;
    my $link  = shift;
    my $this  = {};
    bless($this,$class);
    $this->{"site"} = $link;
    return $this;
}

1;

And the code I'm using to check the functionality is:


use Link;

tie my $var,"Link","http://somesite.com";
$var->print_method;

When ran, the script will terminate with the following error: Can't call method "print_method" without a package or object reference at tietest.pl line 4..

If I understand its message correctly, $var->print_method resolves to some string upon which the method print_method is called. How could I benefit from tie, but also use the variable as an object?

EDIT: after experimenting a bit,I found out that if I return $self on fetch , I can call the methods , however , fetch won't return the address .

EDIT 2:the perl monks supplied me the solution : tied . tied will return a reference to the object VARIABLE .

By combining tied with my methods , I can accomplish everything I wanted .

like image 903
Geo Avatar asked Feb 07 '09 18:02

Geo


1 Answers

Tie is the wrong tool for this job. You use ties when you want the same interface as normal data types but want to customize how the operations do their work. Since you want to access and store a string just like a scalar already does, tie doesn't do anything for you.

It looks like you want the URI module, or a subclass of it, and perhaps some overloading.

If you really need to do this, you need to use the right variable. The tie hooks up the variable you specify to the class you specify, but it's still a normal scalar (and not a reference). You have to use the object it returns if you want to call methods:

my $secret_object = tie my($normal_scalar), 'Tie::Class', @args;
$secret_object->print_method;

You can also get the secret object if you only have the tied scalar:

my $secret_object = tied $normal_scalar;

I have an entire chapter on tie in Mastering Perl.

like image 182
brian d foy Avatar answered Oct 30 '22 16:10

brian d foy