in reply to How Does Interpolation Work?

This is something that bugs me a lot: Is there anyway to interpolate a method call within double quotes:

print "Name is $obj->name";

...right then and there?

/jeorgen

Replies are listed 'Best First'.
RE: Re: How Does Interpolation Work?
by buzzcutbuddha (Chaplain) on Jul 21, 2000 at 16:25 UTC
    Here you go:
    sub yahoo() { return "Easy"; } print "${\yahoo()} does it!\n";
    Never mind the odd sub naming convention, it is the result of too little sleep. :)
    Cheers!
RE: Re: How Does Interpolation Work? (CMonster: method call eval)
by CMonster (Scribe) on Jul 21, 2000 at 21:24 UTC

    Oh, you asked for it!

    Mark-Jason Dominus presented this at the Perl Conference. It's a generic way to evaluate a Perl expression inside a double-quoted string:

    package Eval; sub import { my ($package, $name) = @_; $name = 'Eval' unless defined $name; my %magical_hash; tie %magical_hash =>Eval; my $caller = caller; *{caller . '::' . $name} = \%magical_hash; } sub TIEHASH { my $self = \'fake'; bless $self => Eval; } sub FETCH { my ($self, $value) = @_; $value; }

    Looks pretty freaky, eh? Okay, now try this:

    use Eval => ':'; $salary = 43_000; print "After your raise, you will make $:{$salary*1.06}.\n";

    Yeek. Have fun!

      Thanks for the example, CMonster, but I don't get it to work on my machine (ActiveState 5.005_03).

      I get:

      Warning: Use of "caller" without parens is ambiguous at C:\... line 11. syntax error at C:\... line 29, near "use Eval =>"

      So I change from:

      use Eval => :;

      to:

      use Eval ( ':');

      at line 29.

      Then I get:

      Modification of a read-only value attempted at Eval.pm line 17

      and that one I just don't know what to do about. I tried to change

      my $self = \'fake'

      to:

      my $self = {}

      at line 16, but that didn't help.

      /jeorgen

        I had to make the following changes:
        • Add a $ to the typeglob line: *{$caller . '::' . $name} = \%magical_hash;
        • Do a two-step reference creation in TIEHASH():
          my $self = 'fake'; $self = \$self;
        • Use a more standard use statement: use Eval (':');
        It won't run under strict, though, with the symbolic reference in the import() bit.