With a fairly recent Interpolation.pm you can get almost what you are after:

use strict; package Foo; sub new { my $self = {}; bless $self, 'Foo'; } sub bar { my $self = shift(); if (@_ == 0) { return "Call \$foo->bar()"; } else { return "Call \$foo->bar( '" . join("', '", @_) . "')"; } } package main; my $foo = new Foo; use Interpolation 'foo:$@->$' => sub { my $cmd = shift(); no strict 'refs'; $foo->$cmd(@_); }; # this creates a tied PACKAGE variable %main::foo !!! print "x $foo{bar}\n"; print "x $foo{bar}{1}\n"; print "x $foo{bar}{1,2}\n"; # if you want the arrow just create a reference to the %main::foo my $Foo = \%foo; print "x $Foo->{bar}\n"; print "x $Foo->{bar}{1}\n"; print "x $Foo->{bar}{1,2}\n";

If you do not want to create the global variable you have to use tie(...) instead of use Interpolation ... like this:

... package main; use Interpolation; my $foo = new Foo; my $Foo = {}; tie %$Foo, 'Interpolation::general', sub { my $cmd = shift(); no strict 'refs'; $foo->$cmd(@_); }, '$@->$'; print "x $Foo->{bar}\n"; print "x $Foo->{bar}{1}\n"; print "x $Foo->{bar}{1,2}\n";

Of course this way you have to create a tied hash (or reference to a tied hash) for each object you want to be able to call this way. If you can do that you may create a single %CALL hash and use that one like this:

... package main; use Interpolation; my $foo = new Foo; my $CALL = {}; tie %$CALL, 'Interpolation::general', sub { my $obj = shift(); my $cmd = shift(); no strict 'refs'; $obj->$cmd(@_); }, '$$@->$'; print "x $CALL->{$foo}->{bar}\n"; print "x $CALL->{$foo}->{bar}{1}\n"; print "x $CALL->{$foo}->{bar}{1,2}\n";
but I think this doesn't look good anymore.

Jenda

Update: You may also want to look at Perl6::Interpolators. They might suit you even better.

Update 2: There's one gotcha I should warn you about. The parameters to the methods are converted to strings! So if they were references they are not any longer. And if they contained the character with code 28 ($;) then they will be split up! If this is a problem you have to use a little different syntax:

package Foo; sub baz { my $self = shift(); foreach (@_) { print "$_ is a ".(ref $_ ? "reference" : "string")."\n"; } } ... package main; my $FooX = {}; tie %$FooX, 'Interpolation::general', sub { my $cmd = shift(); no strict 'refs'; $foo->$cmd(@_); }, '$$*->$'; print "x $FooX->{baz}{1}{2}{$foo}\n"; or my $CALLX = {}; tie %$CALLX, 'Interpolation::general', sub { my $obj = shift(); #print "Yep it's a ref\n" if ref $obj; my $cmd = shift(); no strict 'refs'; $obj->$cmd(@_); }, '$$$*->$'; print "x $CALLX->{$foo}->{baz}{$ref}{100}{$object}\n";
I doubt your users will like this though.


In reply to Re: Changing -> to work within a string by Jenda
in thread Changing -> to work within a string by shushu

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.