Hi,
it's definitely not a problem with list-vs-scalar context,
something deeper goes on. Can you try the attached minimal
example (untar, "perl Makefile.PL", "make", and then run test.pl).
It mimicks a call to Gtk2::Image->new_from_file($n)
where $n is (1) a simple scalar and (2) a tied scalar.
You should see a "FETCH(...)" when the tied scalar's FETCH
method is invoked. simple() is a minimal XS sub that
just passes its only parameter down (as an SV*).
I get the following output for Perl 5.8.8 on Debian Linux
(same for Perl 5.8.7 from ActiveState and cygwin):
simple(red.png) at test.pl line 16.
FETCH(Foo=SCALAR(0x81da484)) at test.pl line 6.
# OK: tied scalar's FETCH was invoked for simple($tied_scalar)
simple(blue.png) at test.pl line 17.
gperl_filename_from_sv: got "red.png" at test.pl line 22.
gperl_filename_from_sv: dup "red.png" at test.pl line 22.
gtk_image_new_from_file(red.png) at test.pl line 22.
# now calling Bar->gtk_image_new_from_file($tied_scalar)
# not OK: FETCH missing
gtk_image_new_from_file((null)) at test.pl line 23.
# finally a NULL pointer was passed down
Further inspection shows that the problem is the
filename parameter to the XS sub. It's declared
as a GPerlFilename_ornull. The latter has an input mapping of
$var = ($type)(($arg && SvOK ($arg))
? gperl_filename_from_sv ($arg)
: NULL)
Turns out that SvOK($tied_scalar) is false (but
SvMAGICAL($tied_scalar) is true). That explains why NULL
is passed down.
I tried the same on an old Perl 5.8.0 on Solaris
and there I get the expected second FETCH and indeed
SvOK($tied_scalar) is true there.
AFAICT the check "$arg && SvOK ($arg)" is supposed to be
the XS equivalent of "defined $arg"? Apparently that's
broken for recent Perls when $arg is a tied variable.
Cheers, Roderich
Attachment:
bar.tar.gz
Description: bar.tar.gz