How can I use the string variable expansion for OO "$self->attribute"

  • Thread starter Ilias Lazaridis
  • Start date
I

Ilias Lazaridis

I have working code like this:

{{{
#!perl
my $value = $self->val($attrib);
return "$label: $value";
}}}

I would like to write something like

{{{
#!perl
return "$self->label: $self->val($attrib)";
}}}

is ther ANY way of achieving this, whilst using ONLY the string?

..
 
B

Brian McCauley

I have working code like this:

{{{
#!perl
my $value = $self->val($attrib);
return "$label: $value";

}}}

I would like to write something like

{{{
#!perl
return "$self->label: $self->val($attrib)";

}}}

is ther ANY way of achieving this, whilst using ONLY the string?

Define ONLY.

Even "xxx $foo xxx" is just syntactic sugar for "xxx" . $foo . "xxx".

BTW this is FAQ: "How do I expand function calls in a string?"

See also the Interpolate module and Tie::OneOff. (Tie::OneOff was
originally Tie::Simple but was never realeased under that name. Then
someone else released a substancially identical module under the
originl name!).
 
I

Ilias Lazaridis

Define ONLY.

Even "xxx $foo xxx" is just syntactic sugar for "xxx" . $foo . "xxx".

I like to use this 'syntactic sugar' (and some more, that's the reason
for this thread).
BTW this is FAQ: "How do I expand function calls in a string?"

I've searched for "method" and "attributes", as my main interest is OO
Perl.

I'll search in future for "function", too.

"
In general, this is fraught with quoting and readability problems, but
it is possible. To interpolate a subroutine call (in a list context)
into a string:

print "My sub returned @{[mysub(1,2,3)]} that time.\n"
"
http://www.perlmonks.org/?node=How do I expand function calls in a string?

this solution has problems with readability (as already noted by the
author).
See also the Interpolate module and Tie::OneOff. (Tie::OneOff was
originally Tie::Simple but was never realeased under that name. Then
someone else released a substancially identical module under the
originl name!).

http://search.cpan.org/~nobull/Tie-OneOff/lib/Tie/OneOff.pm
http://perl.plover.com/Interpolation/manual.html

Thanks for the info, but I'm unable to see how I could process this
string:

return "$self->label: $self->val($attrib)"

is there any stand-alone function available (something like
"stringeval"), which would process the string correctly?

If yes (or if I write my own), is there a way to override the default
string-processing behaviour of perl on a per-package basis?

..
 
D

Dr.Ruud

Ilias Lazaridis schreef:
return "$self->label: $self->val($attrib)";
is ther ANY way of achieving this, whilst using ONLY the string?

Just play with it:

perl -e'
my ($self, $attrib) = qw(main 42);
sub val{ "<pkg: $_[0], val:$_[1]>" };
sub label{ "my-label" };

print "$_\n" for
$self->label .": ". $self->val($attrib),
qq(@{[ $self->label ]}: @{[ $self->val($attrib) ]}),
sprintf "%s: %s", $self->label, $self->val($attrib),
;
'
my-label: <pkg: main, val:42>
my-label: <pkg: main, val:42>
my-label: <pkg: main, val:42>
 
I

Ilias Lazaridis

Ilias Lazaridis schreef:


Just play with it:
[...] examples.

I really meant to process this string.

As asked in my other reply:

is there any stand-alone function available (something like
"stringeval"), which would process the string correctly?

If yes (or if I write my own), is there a way to override the default
string-processing behaviour of perl on a per-package basis?

..
 
B

Brian McCauley

BTW this is FAQ: "How do I expand function calls in a string?"

print "My sub returned @{[mysub(1,2,3)]} that time.\n"

this solution has problems with readability (as already noted by the
author).

Everything has problems with readability if abused.
http://search.cpan.org/~nobull/Tie-...p://perl.plover.com/Interpolation/manual.html

Thanks for the info, but I'm unable to see how I could process this
string:

return "$self->label: $self->val($attrib)"

I know of no way. The trick of creating hashes that are really
functions allows you to get function calls to interpolate (because
they look like hashes).
is there any stand-alone function available (something like
"stringeval"), which would process the string correctly?

Not that I know of .
If yes (or if I write my own), is there a way to override the default
string-processing behaviour of perl on a per-package basis?

For string literals yes, not for the interpolation rules. At least not
without resorting to source filters.
 
A

anno4000

Ilias Lazaridis said:
Ilias Lazaridis schreef:


Just play with it:
[...] examples.

I really meant to process this string.

As asked in my other reply:

is there any stand-alone function available (something like
"stringeval"), which would process the string correctly?

Define "correctly". There are serious parsing problems involved
in recognizing arbitrary code that is embedded in a string.

Anno
 
I

Ilias Lazaridis

On Jun 9, 12:57 pm, Ilias Lazaridis <[email protected]> wrote:
[...] - (readability)
[...] - (TieOff module)
I know of no way. The trick of creating hashes that are really
functions allows you to get function calls to interpolate (because
they look like hashes).


Not that I know of .
ok


For string literals yes, not for the interpolation rules. At least not
without resorting to source filters.

ok.

So, it seems if I want to have somethin other like

return sprintf "%s: %s", $self->label, $self->val($attrib);

that I have to code myself something like e.g.:

return sip "$self->label: $self->val($attrib)";

..
 
I

Ilias Lazaridis

Ilias Lazaridis said:
Ilias Lazaridis schreef:
return "$self->label: $self->val($attrib)";
is ther ANY way of achieving this, whilst using ONLY the string?
Just play with it:
[...] examples.
I really meant to process this string.
As asked in my other reply:
is there any stand-alone function available (something like
"stringeval"), which would process the string correctly?

Define "correctly". There are serious parsing problems involved
in recognizing arbitrary code that is embedded in a string.

With "correctly" I meant "As expected by a programmer".

parsing problems are ther to be solved.

anyway, I've just tried to verify that there is no existent
solution available.

As said in the other answer:

So, it seems if I want to have somethin other like

return sprintf "%s: %s", $self->label, $self->val($attrib);

that I have to code myself something like e.g.:

return sip "$self->label: $self->val($attrib)";

..
 
M

Mumia W.

[...]
http://search.cpan.org/~nobull/Tie-OneOff/lib/Tie/OneOff.pm
http://perl.plover.com/Interpolation/manual.html

Thanks for the info, but I'm unable to see how I could process this
string:

return "$self->label: $self->val($attrib)"

Tie::OneOff seems to be very similar to Tie::Sub:

use strict;
use warnings;
require Tie::Sub;
require NetAddr::IP;

my $net = NetAddr::IP->new('loopback');
tie my %sub, 'Tie::Sub', sub {
my $method = shift;
$net->$method;
};

print "My address is $sub{addr}\n";

Tie::Sub makes a function call look like a reference to a hash element,
and interpolation is done for hash elements within double-quoted strings.
is there any stand-alone function available (something like
"stringeval"), which would process the string correctly?

Probably not.
If yes (or if I write my own), is there a way to override the default
string-processing behaviour of perl on a per-package basis?

You could create a source filter. Install Filter::Simple and read these:

perldoc perlfilter
perldoc Filter::Simple

I think Tie::Sub is much simpler.
 
I

Ilias Lazaridis

Thanks for the info, but I'm unable to see how I could process this
string:
return "$self->label: $self->val($attrib)"

Tie::OneOff seems to be very similar to Tie::Sub:

use strict;
use warnings;
require Tie::Sub;
require NetAddr::IP;

my $net = NetAddr::IP->new('loopback');
tie my %sub, 'Tie::Sub', sub {
my $method = shift;
$net->$method;
};

print "My address is $sub{addr}\n";

Tie::Sub makes a function call look like a reference to a hash element,
and interpolation is done for hash elements within double-quoted strings.

This would be too much overhead.
Probably not.


You could create a source filter. Install Filter::Simple and read these:

perldoc perlfilter
perldoc Filter::Simple

ok, very nice!
I think Tie::Sub is much simpler.

Personally I would prefer sprintf (if no other solution available, or
no
time to implement a solution).

..
 
D

Dr.Ruud

Ilias Lazaridis schreef:
So, it seems if I want to have somethin other like

return sprintf "%s: %s", $self->label, $self->val($attrib);

that I have to code myself something like e.g.:

return sip "$self->label: $self->val($attrib)";

See also `perldoc overload`.
 
I

Ilias Lazaridis

IL>http://www.tu-chemnitz.de/docs/perldoc-html/overload.html

perldoc.perl.org has all the docs and so does your own perl
installation.

IL> btw: can I actually overload the "@" and "%", too - thus my custom
IL> Array/Hash class is used?

overloading is for operators, tie (perldoc perltie) is for replacing
variables with an OO implementation.

I've looked at this (giving first relevant search hit for 'perltie'):

http://www.tu-chemnitz.de/docs/perldoc-html/perltie.html#Tying-Arrays-array,-tying

but I cannot see how I can overload / tie the default array to
MyArray, e.g. with a statement like:

use array 'MyArray';

my @data = ('peter', 'paul');
@data->isa('MyArray'); #=> returns true

..
 
U

Uri Guttman

IL> I've looked at this (giving first relevant search hit for 'perltie'):

IL> http://www.tu-chemnitz.de/docs/perldoc-html/perltie.html#Tying-Arrays-array,-tying

stop using a search engine for perl docs. go to perldoc.perl.org which
has all of the docs. also YOUR perl has all the docs. please learn to
use perldoc as it will save you time and trouble.

IL> but I cannot see how I can overload / tie the default array to
IL> MyArray, e.g. with a statement like:

what is a default array?

IL> use array 'MyArray';

you use a tie statement. there are many tie modules on cpan and plenty
of docs on how to create a tied array.

IL> my @data = ('peter', 'paul');
IL> @data->isa('MyArray'); #=> returns true

that has nothing to do with tying. in fact that looks like a syntax
error. please read the perldoc perltie (don't search for it). look on
cpan for tied array modules as most will have examples of how to do the
tying.

uri
 
I

Ilias Lazaridis

IL>http://www.tu-chemnitz.de/docs/perldoc-html/overload.html

perldoc.perl.org has all the docs and so does your own perl
installation.

IL> btw: can I actually overload the "@" and "%", too - thus my custom
IL> Array/Hash class is used?

overloading is for operators, tie (perldoc perltie) is for replacing
variables with an OO implementation.

I cannot findout how to implement this below with perltie:


perl [http://search.cpan.org/~nwclark/perl-5.8.8/lib/overload.pm
overload] provides functionality for operators:

{{{
#!perl
use overload
'+' => \&myadd,
'-' => \&mysub;
# etc
...
}}}

is there a similar module to overload the classes of build in types
(like array), something like:

{{{
#!perl
use typeoverload
'@' => 'My::Array',
'%' => 'My::Hash';
# etc
...
}}}

..
 
U

Uri Guttman

IL> I cannot findout how to implement this below with perltie:

IL> perl [http://search.cpan.org/~nwclark/perl-5.8.8/lib/overload.pm
IL> overload] provides functionality for operators:

as i said before tie is for variables. it is NOT related to
overload. don't try to make them the same thing as they do very
different things.

IL> is there a similar module to overload the classes of build in types
IL> (like array), something like:

IL> {{{
IL> #!perl
IL> use typeoverload
IL> '@' => 'My::Array',
IL> '%' => 'My::Hash';
IL> # etc
IL> ...
IL> }}}

it is called tie. it is documented. there are many examples of this on
cpan. look for them and learn how to do this. you can't do this for all
variables at one time. you tie an individual variable to a class which
implements it.

uri
 
M

Mumia W.

[...]
is there a similar module to overload the classes of build in types
(like array), something like:

{{{
#!perl
use typeoverload
'@' => 'My::Array',
'%' => 'My::Hash';
# etc
...
}}}

..

You don't want to do that, and thankfully Perl won't let you. Do you
seriously want to make every low-level Perl array access attempt go
through My::Array?

If it were me, I'd just use the traditional syntax for interpolating
complex expressions within strings @{[ $self->val($attrib) ]}. You seem
to think that's ugly. To each his own.

There is little chance that the path you are on right now will lead you
to success, and there's almost no chance that you'll find a more
efficient and simple solution than Tie::Sub.

Oh well. Good luck.
 
I

Ilias Lazaridis

IL> I've looked at this (giving first relevant search hit for 'perltie'):

IL>http://www.tu-chemnitz.de/docs/perldoc-html/perltie.html#Tying-Arrays...

stop using a search engine for perl docs. go to perldoc.perl.org which
has all of the docs. also YOUR perl has all the docs. please learn to
use perldoc as it will save you time and trouble.

please!

I just provide links, thus future readers can follow the thread
immediately.
IL> but I cannot see how I can overload / tie the default array to
[...] - (tie etc.)

(duplicate message due to problems with google-groups)

relevant comments here:

http://groups.google.com/group/comp.lang.perl.misc/msg/0a355d7ecbd4747c

..
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top