Dmitry,
there are a couple of reasons why i am going away with the:
perl_eval('@x = 1..10');
var_dump(perl_var('@x'));
approach:
- i don't want to force the users to use 2 statments just to get a single
value out. - some variables don't have names and i want my users to be able to do
stuff like:
print_r(p2p_eval('[1..10]'));
print_r(p2p_eval('{a => 1,b => 2}'));
if pecl/perl already does that then we should encourage users to use the
single statement notation for short Perl expressions.
function and method calls are handled similiarly and it's the context within
Perl that controls the context of the final variables returned back to PHP.
for example:
$k = p2p_eval('use Foo; $x = Foo->new; scalar $x->method');
will return a scalar to $k but:
$k = p2p_eval('[$x->method]');
will return an array to $k and
$k = p2p_eval('{$x->method}');
will return a hash to $k. note the package Foo is only loaded once and
"remembered" so it doesn't need to be loaded again. the reason why i chose
this method:
- i don't want to introduce new syntax to the PHP language. i think someone
suggest something like:
$x->scalar->method; // for scalar context
$x->array->method; // for array context
$x->hash->method; // for hash context
i think this will complicate the langauge down the road. also, in void
context, you need to:
$x->void->method; // which doesn't "look" right.
- most Perl programmers are already familiar with the notation of:
p2p_eval('[...]'); // array
p2p_eval('{...}'); // hash
p2p_eval('$x'); // scalar
becaue the [],{}, and $ makes it clear what "things" are returned. for
function calls, i also have another method named p2p_map that does something
like:
$v = p2p_eval('sub{[$[0]+1, $[1]+2, $[2]+3, $[3]+4]}',array(1,2,3,4));
print_r($v);
prints:
Array
(
[0] => 2
[1] => 4
[2] => 6
[3] => 7
)
the second argument is supplied to the first argument (which is a code
reference) and consequencely become the input of the Perl function. again,
the result is returned base on the context within the Perl code, PHP doesn't
(and shouldn't) care.
my extension still have a lot of problem that needs to be solved, for
example, Perl glob, I/O handle and some complicated data structures aren't
handled correctly. unfortunately, i do not have a lot of time to work on it
(i did it for fun) but i want to share my experience with you so maybe you
can think about some of the stuff that i did and have some more ideas.
thanks!
david
-----Original Message-----
From: Dmitry Stogov [mailto:d.stogov@gmx.net]
Sent: Friday, March 05, 2004 1:56 AM
To: David Zhuo
Cc: internals@lists.php.net
Subject: RE: [PHP-DEV] Re: Perl extension
pecl/perl can work in the simular way.
It don't return value in same context as latest assignment (like
p2p_eval does), but it allows to get perl variable's value.
<?php
perl_eval('$x = 10');
var_dump(perl_var('$x'));
perl_eval('@x = 1..10');
var_dump(perl_var('@x'));
perl_eval('%x = 1..10');
var_dump(perl_var('%x'));
$k = perl_eval("'x1234y' =~ /(\d+)/; $1");
var_dump($k);
?>
I will think about your way to determine return context for perl_eval,
but unfortunately it can't be used for functions and methods calls.
Dmitry.
-----Original Message-----
From: david [mailto:dzhuo@looksmart.net]
Sent: Thursday, March 04, 2004 02:11
To: internals@lists.php.net
Subject: [PHP-DEV] Re: Perl extensionAndi Gutmans wrote:
Hey,
As some of you might have noticed, Dmitry worked on a Perl
extension
which allows PHP to run Perl scripts as well as instantiate Perl
objects in PHP and use them.i have done something similiar in the pass but with a
different approach. i
have written a PHP extension where it's capable of running
any arbitary
Perl code and return the result back to PHPThe main problem with the extension is the fact that Perl functions
behave differently according to their context (scalar/array) which
doesn't exist in PHP. We thought of all sorts of ways to solve this
problem but aren't sure what the best approach would be.
The current
implementation uses scalar as default, and if you want an
array, you
can use perl_wantarray() and the next method call would return an
array (the one after that would return scalar):Example:
$x = new Perl("Test");
$y = $x->f(); // scalar context;
perl_wantarray();
$y = $x->f(); // array context;
$y = $x->f(); // scalar context;in my extension, i have handled this situation base on the
context within
the Perl code, not in PHP. everything is passed back to PHP
as reference
except for scalar. the reference is then dereferenced base on
the "type"
they are point to so for example:<?php
dl("perl.so");
$k = p2p_eval("%k = 1..10; %k");
print_r($k)
?>
prints:
Array
(
[1] => 2
[3] => 4
[7] => 8
[9] => 10
[5] => 6
)which returns a hash to $k but:
$k = p2p_eval("@k = 1..10; @k");
print_r($k);
prints:
Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
[4] => 5
[5] => 6
[6] => 7
[7] => 8
[8] => 9
[9] => 10
)which returns an array back to $k because the last expression
of the Perl
code evaluates to an array reference. scalars are returned by value:$k = p2p_eval("'x1234y' =~ /(\d+)/; $1");
print_r($k);
prints:
1234
this way, i don't have to concern about what context the PHP
code is being
used as long as the Perl code returns the right thing in the
right context,
my extension will handle the data type correctly.just something to share...
david
s$s*$+/<tgmecJ"ntgR"tgjvqpC"vuwL$;$;=qq$
\x24\x5f\x3d\x72\x65\x76\x65\x72\x73\x65
\x24\x5f\x3b\x73\x2f\x2e\x2f\x63\x68\x72
\x28\x6f\x72\x64\x28\x24\x26\x29\x2d\x32
\x29\x2f\x67\x65\x3b\x70\x72\x69\x6e\x74
\x22\x24\x5f\x5c\x6e\x22\x3b\x3b$;eval$;