Open rwp0 opened 4 weeks ago
I'd expect stringify X
to be equivalent to "" . X
, i.e. evaluate in scalar context and convert to string. Your example behaves the way I expect.
Variable interpolation is more complicated. For scalars it just stringifies, but "@foo"
is equivalent to join($", @foo)
, and "%foo"
is just '%foo'
(hashes don't interpolate at all). It doesn't make sense to me to use this as our model.
Indeed; builtin::stringify
has a prototype of ($)
, i.e. takes a single scalar argument. It gets parsed as builtin::stringify scalar @array
; and thus the expected result is a string containing the decimal representation of the count of items in the array.
However I think it's a valid observation that the documentation doesn't point out this, so maybe some more words could be added to better explain it.
Indeed;
builtin::stringify
has a prototype of($)
, i.e. takes a single scalar argument. It gets parsed asbuiltin::stringify scalar @array
; and thus the expected result is a string containing the decimal representation of the count of items in the array.
Should it be called scalarify instead? (?! Or scalarify_and_then_stringify?) It is confusing if it works like "" but not always?
Edit: Ok, that question isn't that good. But perhaps the subset of stringifying it is doing deserves an even more accurate name?
Edit 2: concatify?
Edit 3:
$ cat test_stringify.t
no warnings 'experimental::builtin';
use builtin qw/stringify/;
use Test::More;
my $str = "hi",
my $num = 1.01,
my @array = ( 1, 2, 3 );
my %hash = ( a => 8 );
my $array_ref = [ 4, 5, 6 ];
my $hash_ref = { b => 9 };
my $obj = bless {}, 'something';
subtest "concatify" => sub {
is stringify($str), "" . $str, 'string';
is stringify($num), "" . $num, 'number';
is stringify(@array), "" . @array, 'array';
is stringify(%hash), "" . %hash, 'hash';
is stringify($array_ref), "" . $array_ref, 'array_ref';
is stringify($hash_ref), "" . $hash_ref, 'hash_ref';
is stringify($obj), "" . $obj, 'object';
};
subtest "stringify" => sub {
is stringify($str), "$str", 'string';
is stringify($num), "$num", 'number';
is stringify(@array), "@array", 'array';
is stringify(%hash), "%hash", 'hash';
is stringify($array_ref), "$array_ref", 'array_ref';
is stringify($hash_ref), "$hash_ref", 'hash_ref';
is stringify($obj), "$obj", 'object';
};
done_testing;
$ prove -e './perl -I./lib' -lvr test_stringify.t
test_stringify.t ..
# Subtest: concatify
ok 1 - string
ok 2 - number
ok 3 - array
ok 4 - hash
ok 5 - array_ref
ok 6 - hash_ref
ok 7 - object
1..7
ok 1 - concatify
# Subtest: stringify
ok 1 - string
ok 2 - number
not ok 3 - array
# Failed test 'array'
# at test_stringify.t line 27.
# got: '3'
# expected: '1 2 3'
not ok 4 - hash
# Failed test 'hash'
# at test_stringify.t line 28.
# got: '1'
# expected: '%hash'
ok 5 - array_ref
ok 6 - hash_ref
ok 7 - object
1..7
# Looks like you failed 2 tests of 7.
not ok 2 - stringify
# Failed test 'stringify'
# at test_stringify.t line 32.
1..2
# Looks like you failed 1 test of 2.
Dubious, test returned 1 (wstat 256, 0x100)
Failed 1/2 subtests
Test Summary Report
-------------------
test_stringify.t (Wstat: 256 (exited 1) Tests: 2 Failed: 1)
Failed test: 2
Non-zero exit status: 1
Files=1, Tests=2, 0 wallclock secs ( 0.01 usr 0.00 sys + 0.02 cusr 0.00 csys = 0.03 CPU)
Result: FAIL
No. Stringification (i.e. "convert value to string") is neither interpolation nor quoting.
Would you expect stringify(1 + 2*3)
to be equal to "1 + 2*3"
? If so, that's not a function. You want a quoting operator like qq(1 + 2*3)
instead.
Similarly:
my %h = (a => 42);
say stringify(%{\%h}); # 1
say "%{\%h}"; # %{%h}
my $r = \%h;
say stringify(%{$r}); # 1
say "%{$r}"; # %{HASH(0x420b0ff0)}
There is no way for a normal function to distinguish between f(%{ \%hash })
and f(%{ $ref })
and to somehow recover the variable name (%hash
) in the former case.
@mauke I am mostly considered about consistency and least surprises. Sure, the string interpolation of a hash is a bit weird as it is, specicially compared to the magic for an array.
As you can see by the tests I added, stringify() is currently behaving exactly like concatenating to a string, if that's what stringification really means – that's fair. Then I have to alter my expectations and learn that there is a clear difference between interpolation and stringification.
The documentation doesn't mention the effect of
builtin::stringify
function on arrays.I expected it to act in a similar fashion to
""
double quotes.Is it that the
2
numerical value is turned internally to a string value here?Is this behavior normal and the results expected?
Do we need to mention the function's effect on arrays (and perhaps hashes too) in the documentation?
I was assuming that
stringify
is mostly equal to""
string context (with variable interpolation).Thanks