Git Product home page Git Product logo

function-parameters's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

function-parameters's Issues

Can't have slurpy array with named parameters

Using a slurpy array with named parameters generates this warning:

Odd number of paired arguments for method my_method at test.pl line 10.

method my_method (:$id, @args) {

}

It would be nice if an array could be slurpy after named parameters.

Passing the same named parameter multiple times should be an error.

As with hash initialization, you can specify the same key
multiple times and the last occurrence wins:

    rectangle(height => 1, width => 2, height => 2, height => 5);
    # same as: rectangle(width => 2, height => 5);

I don't see why this should be a documented feature. IMO it's going to be a mistake far more often than it's intended. The only time I can think this is a good idea is to override the defaults. Method::Signatures explicitly disallows it.

The same feature can be implemented by putting the options into a hash first. This has the advantage of being explicit. It's going to be pretty rare, so the extra code is ok.

my %defaults = (height => 1, width => 2);
my %args = (%defaults, %your_args);
rectangle(%args);

The Perl idea that parameters are just a list (or list being flattened into a hash) is a weird language quirk. Function parameters should not hold over those quirks.

Make `fun foo` equivalent to `func foo()` under strict.

Strict function parameters are about explicitly expressing intent and preventing mistakes, by both the caller and by the person writing the function. fun foo should be equivalent to fun foo() (same for methods) when strict parameters are on.

Intent: Does fun foo mean the author forgot the parameter list? Or does it mean it takes no parameters? Now I'm back to examining the body of the routine to figure it out, something parameters are there to prevent.

Mistakes: It's really easy to forget the parameter list in a function that takes no parameters, Perl programmers are trained that way. The caller will get no warnings nor errors that their arguments are being thrown away.

Compatibility with Perl 5: Since Function::Parameters is not using sub, it has no need to be compatible like Perl 5 does. Not using sub signals to the user that things are different now.

Backward Compatibility This will make F::P backwards incompatible for users of strict mode. On the up side, their tests will catch it real fast and there's a cross-compatible solution, always use empty parameters.

Expectations: The user asked for strict parameters. Give them strict parameters! Users may not realize the behavior exists, but that will only last until they run their code and get a good error message.

Alternative: Disallow no parameter list entirely under strict, then you must be explicit.

Types obscure earlier compile errors.

I was re-adapting error_interruption.t from Method::Signatures and noticed Function::Parameters has the same problem MS did but only if the signature is using types. The existing adaptation of error_interruption.t removed the type.

# in BarfyDie.pm
package BarfyDie;

use strict;
use Function::Parameters;

$foo = 'hi!';

method foo (Str $bar) {}

1;

If you load this directly, it throws the correct error message, but then it has some bogus error about type constraints.

$ perl -w ~/tmp/BarfyDie.pm 
Global symbol "$foo" requires explicit package name at /Users/schwern/tmp/BarfyDie.pm line 7.
BEGIN not safe after errors--compilation aborted at /Users/schwern/perl5/perlbrew/perls/perl-5.18.1-thread/lib/site_perl/5.18.1/darwin-thread-multi-2level/Moose/Util/TypeConstraints.pm line 5.
Compilation failed in require at /Users/schwern/devel/Function-Parameters/blib/lib/Function/Parameters.pm line 58.

But if you load it as a module, it gives you a bogus error message about type constraints obscuring the real error.

$ perl -Mblib -I ~/tmp/ -wle 'require BarfyDie'
BEGIN not safe after errors--compilation aborted at /Users/schwern/perl5/perlbrew/perls/perl-5.18.1-thread/lib/site_perl/5.18.1/darwin-thread-multi-2level/Moose/Util/TypeConstraints.pm line 5.
Compilation failed in require at /Users/schwern/devel/Function-Parameters/blib/lib/Function/Parameters.pm line 58.
Compilation failed in require at -e line 1.

I suspect either an $@ is leaking out, or something is plowing ahead after the compilation has already failed.

If you remove the type constraint it works as expected.

Should strict include check_argument_types?

if (exists $type{strict}) {
$type{check_argument_count} ||= $type{strict};
delete $type{strict};
}

Should this section here also set check_argument_types? The use case is I'd like to be able to do

use Function::Parameters qw(:lax)

and have Function::Parameters be effectively a no-op. I could send a PR but this might be a breaking change for existing users.

Any thoughts?

Add //= and ||=

Defaults are normally applied when the argument isn't passed in at all. This leaves the problem of what to do when an arg is undefined or false.

fun hello($place="World") { print "Hello, $place!\n" }
hello();  # "Hello, $place!
hello(undef);  # "Hello, !"

To fix that you can't have the default in the parameter list, you're back to doing it in the body. Any time the user has to revert to doing parameter parsing in the body that defeats the point of using parameter lists. It's a sign the parameter syntax isn't expressive enough.

fun hello($place) { $place //= "World";  print "Hello, $place!\n" }

Perl programmers do some wacky things with function arguments, but applying a default if the value is undefined or false is pretty common. Perl already has syntax for that, //= and ||=. So just support that!

Line numbers broken by typed parameter

Running this three-line perl program:

use Function::Parameters { fun => { reify_type => 'moose' } };
fun f( Num $x ) { }
die;

produces Died at f.pl line 8..

This is perl 5.36 on OpenBSD current. EDIT: and Function::Parameters 2.002002.

2.001003: self test failure

On NetBSD with perl-5.26.1, Package-DeprecationManager-0.17, and Moose-2.2006, one self test fails:

t/foreign/Fun/name.t .................................... 1/?
#   Failed test at t/foreign/Fun/name.t line 25.
#                   'abc 123 at t/foreign/Fun/name.t line 15.
#       Foo::foo("\"abc\"", 123) called at t/foreign/Fun/name.t line 19
#       eval {...} called at t/foreign/Fun/name.t line 18
# '
#     doesn't match '(?^:^abc 123 at t\/foreign\/Fun\/name\.t line 15\.?\n\tFoo::foo\((["'])abc\1, 123\) called at t\/foreign\/Fun\/name\.t line 19)'
# Looks like you failed 1 test of 2.
t/foreign/Fun/name.t .................................... Dubious, test returned 1 (wstat 256, 0x100)
Failed 1/2 subtests

1.0501 fails to build

Hi,

Was trying out your latest release and came across this problem during a cpanm install:

cpanm (App::cpanminus) 1.7001 on perl 5.020001 built for x86_64-linux-thread-multi
Work directory is /home/adam/.cpanm/work/1413248175.32321
You have make /usr/bin/make
You have LWP 6.08
You have /bin/tar: tar (GNU tar) 1.27.1
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by John Gilmore and Jay Fenlason.
You have /usr/bin/unzip
Searching Function::Parameters on cpanmetadb ...
--> Working on Function::Parameters
Fetching http://www.cpan.org/authors/id/M/MA/MAUKE/Function-Parameters-1.0501.tar.gz
-> OK
Unpacking Function-Parameters-1.0501.tar.gz
Entering Function-Parameters-1.0501
Checking configure dependencies from META.json
Checking if you have warnings 0 ... Yes (1.23)
Checking if you have strict 0 ... Yes (1.08)
Checking if you have ExtUtils::MakeMaker 6.48 ... Yes (6.98)
Configuring Function-Parameters-1.0501
Running Makefile.PL
Checking if your kit is complete...
Looks good
Generating a Unix-style Makefile
Writing Makefile for Function::Parameters
Writing MYMETA.yml and MYMETA.json
-> OK
Checking dependencies from MYMETA.json ...
Checking if you have XSLoader 0 ... Yes (0.17)
Checking if you have warnings 0 ... Yes (1.23)
Checking if you have Carp 0 ... Yes (1.3301)
Building Function-Parameters-1.0501
cp lib/Function/Parameters/Info.pm blib/lib/Function/Parameters/Info.pm
cp lib/Function/Parameters.pm blib/lib/Function/Parameters.pm
Running Mkbootstrap for Function::Parameters ()
chmod 644 Parameters.bs
/home/adam/perl5/perlbrew/perls/5.20.1t/bin/perl /home/adam/perl5/perlbrew/perls/5.20.1t/lib/5.20.1/ExtUtils/xsubpp  -typemap /home/adam/perl5/perlbrew/perls/5.20.1t/lib/5.20.1/ExtUtils/typemap  Parameters.xs > Parameters.xsc && mv Parameters.xsc Parameters.c
cc -c   -D_REENTRANT -D_GNU_SOURCE -fwrapv -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -O2   -DVERSION=\"1.0501\" -DXS_VERSION=\"1.0501\" -fPIC "-I/home/adam/perl5/perlbrew/perls/5.20.1t/lib/5.20.1/x86_64-linux-thread-multi/CORE"   Parameters.c
Parameters.xs: In function ‘parse_param’:
Parameters.xs:959:46: warning: passing argument 1 of ‘mkconstsv’ from incompatible pointer type
             op_guard_update(ginit, mkconstsv(&PL_sv_undef));
                                              ^
Parameters.xs:780:12: note: expected ‘struct PerlInterpreter *’ but argument is of type ‘struct SV *’
 static OP *mkconstsv(pTHX_ SV *sv) {
            ^
Parameters.xs:959:36: error: too few arguments to function ‘mkconstsv’
             op_guard_update(ginit, mkconstsv(&PL_sv_undef));
                                    ^
Parameters.xs:780:12: note: declared here
 static OP *mkconstsv(pTHX_ SV *sv) {
            ^
Makefile:341: recipe for target 'Parameters.o' failed
make: *** [Parameters.o] Error 1
-> FAIL Installing Function::Parameters failed. See /home/adam/.cpanm/work/1413248175.32321/build.log for details. Retry with --force to force install it.

Slurpies are assumed to be optional

Method::Signatures supports required slurpies.

$ perl -MMethod::Signatures -wle 'method foo (@foo!) {} main->foo'
In call to main::foo(), missing required argument @foo at -e line 1.

The idea that slurpies are always optional is baked pretty deep into Function::Parameters and I'm having difficulty enforcing the requirement.

Better error message for slurpy in the wrong place.

$ perl -wle 'use Function::Parameters; fun foo(@that, $this) {}'
In fun foo: I was expecting ")" after "@that", not "$this" at -e line 1.

How about "Slurpy @that must come at the end"?

$ perl -wle 'use Function::Parameters; fun foo($this, @that, @foo) {}'
In fun foo: I was expecting ")" after "@that", not "@foo" at -e line 1.

How about "There is already a slurpy, @that. @foo is an extra"?

Devel::Cover hangs when used with Function::Parameters

My test scripts hang when I run them with Devel::Cover. I narrowed it down to Function::Parameters.

I have a minimal test case here: https://github.com/sdt/devel-cover-function-parameters-hang

This code is enough to reproduce the hang:

fun double($x) {
    return add($x, $x);
}

fun add($x, $y) {
    return $x + $y;
}

Re-ordering those so that add is defined before double makes the problem go away. Setting the runtime flag also makes the problem go away (but causes other errors).

This has already been reported at pjcj/Devel--Cover#164 - I've added this test case to that bug as well.

The invocant is not an argument.

$ perl -wle 'use Function::Parameters qw(:strict);  method foo($bar) {}  main->foo()'
Too few arguments for method foo (expected 2, got 1) at -e line 1.
    main::foo("main") called at -e line 1

I would expect that to say "expected 1, got 0".

From the caller's point of view, the invocant is not an argument. If you asked someone how many arguments are being passed to $obj->method(1, 2, 3) they'd say three, not four. That Perl methods put the invocant on the argument stack is an odd quirk of Perl.

2.40: test suite is failing

perl 5.32.0

+ /usr/bin/perl Makefile.PL INSTALLDIRS=vendor NO_PACKLIST=1 NO_PERLLOCAL=1 
Checking if your kit is complete...
Looks good
Generating a Unix-style Makefile
Writing Makefile for Function::Parameters
Writing MYMETA.yml and MYMETA.json
+ /usr/bin/make -O -j48 V=1 VERBOSE=1
Running Mkbootstrap for Parameters ()
chmod 644 "Parameters.bs"
"/usr/bin/perl" -MExtUtils::Command::MM -e 'cp_nonempty' -- Parameters.bs blib/arch/auto/Function/Parameters/Parameters.bs 644
cp lib/Function/Parameters/Info.pm blib/lib/Function/Parameters/Info.pm
cp lib/Function/Parameters.pm blib/lib/Function/Parameters.pm
"/usr/bin/perl" "/usr/share/perl5/vendor_perl/ExtUtils/xsubpp"  -typemap '/usr/share/perl5/ExtUtils/typemap'  Parameters.xs > Parameters.xsc
mv Parameters.xsc Parameters.c
gcc -c   -D_REENTRANT -D_GNU_SOURCE -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -flto=auto -flto-partition=none -fwrapv -fno-strict-aliasing -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64    -DVERSION=\"2.001003\" -DXS_VERSION=\"2.001003\" -fPIC "-I/usr/lib64/perl5/CORE"   Parameters.c
rm -f blib/arch/auto/Function/Parameters/Parameters.so
gcc  -lpthread -shared -Wl,-z,relro -Wl,--as-needed -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -flto=auto -flto-partition=none -fuse-linker-plugin -L/usr/local/lib -fstack-protector-strong  Parameters.o  -o blib/arch/auto/Function/Parameters/Parameters.so  \
    -lperl   \

chmod 755 blib/arch/auto/Function/Parameters/Parameters.so
Manifying 2 pod documents
+ RPM_EC=0
++ jobs -p
+ exit 0
Executing(%install): /bin/sh -e /var/tmp/rpm-tmp.VaWjqz
+ umask 022
+ cd /home/tkloczko/rpmbuild/BUILD
+ '[' /home/tkloczko/rpmbuild/BUILDROOT/perl-Function-Parameters-2.001003-10.fc33.x86_64 '!=' / ']'
+ /usr/bin/rm -rf /home/tkloczko/rpmbuild/BUILDROOT/perl-Function-Parameters-2.001003-10.fc33.x86_64
+ /usr/bin/mkdir /home/tkloczko/rpmbuild/BUILDROOT/perl-Function-Parameters-2.001003-10.fc33.x86_64
+ cd Function-Parameters-2.001003
+ /usr/bin/make install DESTDIR=/home/tkloczko/rpmbuild/BUILDROOT/perl-Function-Parameters-2.001003-10.fc33.x86_64 'INSTALL=/usr/bin/install -p'
"/usr/bin/perl" -MExtUtils::Command::MM -e 'cp_nonempty' -- Parameters.bs blib/arch/auto/Function/Parameters/Parameters.bs 644
Manifying 2 pod documents
Files found in blib/arch: installing files in blib/lib into architecture dependent library tree
Installing /home/tkloczko/rpmbuild/BUILDROOT/perl-Function-Parameters-2.001003-10.fc33.x86_64/usr/lib64/perl5/vendor_perl/auto/Function/Parameters/Parameters.so
Installing /home/tkloczko/rpmbuild/BUILDROOT/perl-Function-Parameters-2.001003-10.fc33.x86_64/usr/lib64/perl5/vendor_perl/Function/Parameters.pm
Installing /home/tkloczko/rpmbuild/BUILDROOT/perl-Function-Parameters-2.001003-10.fc33.x86_64/usr/lib64/perl5/vendor_perl/Function/Parameters/Info.pm
Installing /home/tkloczko/rpmbuild/BUILDROOT/perl-Function-Parameters-2.001003-10.fc33.x86_64/usr/share/man/man3/Function::Parameters.3pm
Installing /home/tkloczko/rpmbuild/BUILDROOT/perl-Function-Parameters-2.001003-10.fc33.x86_64/usr/share/man/man3/Function::Parameters::Info.3pm
+ /usr/bin/chmod 755 /home/tkloczko/rpmbuild/BUILDROOT/perl-Function-Parameters-2.001003-10.fc33.x86_64/usr/lib64/perl5/vendor_perl/auto/Function/Parameters/Parameters.so
+ /usr/lib/rpm/find-debuginfo.sh -j48 --strict-build-id -m -i --build-id-seed 2.001003-10.fc33 --unique-debug-suffix -2.001003-10.fc33.x86_64 --unique-debug-src-base perl-Function-Parameters-2.001003-10.fc33.x86_64 --run-dwz --dwz-low-mem-die-limit 10000000 --dwz-max-die-limit 110000000 -S debugsourcefiles.list /home/tkloczko/rpmbuild/BUILD/Function-Parameters-2.001003
explicitly decompress any DWARF compressed ELF sections in /home/tkloczko/rpmbuild/BUILDROOT/perl-Function-Parameters-2.001003-10.fc33.x86_64/usr/lib64/perl5/vendor_perl/auto/Function/Parameters/Parameters.so
extracting debug info from /home/tkloczko/rpmbuild/BUILDROOT/perl-Function-Parameters-2.001003-10.fc33.x86_64/usr/lib64/perl5/vendor_perl/auto/Function/Parameters/Parameters.so
original debug info size: 244kB, size after compression: 236kB
/usr/lib/rpm/sepdebugcrcfix: Updated 1 CRC32s, 0 CRC32s did match.
312 blocks
+ /usr/lib/rpm/check-buildroot
+ /usr/lib/rpm/redhat/brp-ldconfig
+ /usr/lib/rpm/brp-compress
+ /usr/lib/rpm/brp-strip-static-archive /usr/bin/strip
+ /usr/lib/rpm/brp-python-bytecompile /usr/bin/python 1 0
+ /usr/lib/rpm/brp-python-hardlink
+ /usr/lib/rpm/redhat/brp-mangle-shebangs
Executing(%check): /bin/sh -e /var/tmp/rpm-tmp.xeUaWz
+ umask 022
+ cd /home/tkloczko/rpmbuild/BUILD
+ cd Function-Parameters-2.001003
+ /usr/bin/make -O -j48 V=1 VERBOSE=1 test
"/usr/bin/perl" -MExtUtils::Command::MM -e 'cp_nonempty' -- Parameters.bs blib/arch/auto/Function/Parameters/Parameters.bs 644
PERL_DL_NONLAZY=1 "/usr/bin/perl" "-MExtUtils::Command::MM" "-MTest::Harness" "-e" "undef *Test::Harness::Switches; test_harness(0, 'blib/lib', 'blib/arch')" t/*.t t/*/*/*.t
# Testing Function::Parameters 2.001003, Perl 5.032000, /usr/bin/perl
t/00-load.t ............................................. ok
t/01-compiles.t ......................................... ok
t/02-compiles.t ......................................... ok
t/03-compiles.t ......................................... ok
t/attributes.t .......................................... ok
t/bonus.t ............................................... ok
t/checkered.t ........................................... ok
t/checkered_2.t ......................................... ok
t/checkered_3.t ......................................... ok
t/checkered_4.t ......................................... ok
t/croak.t ............................................... ok
t/defaults.t ............................................ ok
t/defaults_bare.t ....................................... ok
t/defaults_regress.t .................................... ok
t/eating_strict_error.t ................................. ok
t/elsewhere.t ........................................... ok
t/eval.t ................................................ ok
t/foreign/Fun/anon.t .................................... ok
t/foreign/Fun/basic.t ................................... ok
t/foreign/Fun/closure-proto.t ........................... ok
t/foreign/Fun/compile-time.t ............................ ok
t/foreign/Fun/defaults.t ................................ ok
t/foreign/Fun/name.t .................................... ok
t/foreign/Fun/package.t ................................. ok
t/foreign/Fun/recursion.t ............................... ok
t/foreign/Fun/slurpy-syntax-errors.t .................... ok
t/foreign/Fun/slurpy.t .................................. ok
t/foreign/Fun/state.t ................................... ok
t/foreign/Method-Signatures-Simple/02-use.t ............. ok
t/foreign/Method-Signatures-Simple/03-config.t .......... ok
t/foreign/Method-Signatures-Simple/RT80505.t ............ ok
t/foreign/Method-Signatures-Simple/RT80507.t ............ ok
t/foreign/Method-Signatures-Simple/RT80508.t ............ ok
t/foreign/Method-Signatures-Simple/RT80510.t ............ ok
t/foreign/Method-Signatures/anon.t ...................... ok
t/foreign/Method-Signatures/array_param.t ............... ok
t/foreign/Method-Signatures/at_underscore.t ............. ok
t/foreign/Method-Signatures/attributes.t ................ ok
t/foreign/Method-Signatures/begin.t ..................... ok
t/foreign/Method-Signatures/caller.t .................... ok
t/foreign/Method-Signatures/comments.t .................. ok
t/foreign/Method-Signatures/defaults.t .................. ok
t/foreign/Method-Signatures/error_interruption.t ........ ok
t/foreign/Method-Signatures/func.t ...................... ok
t/foreign/Method-Signatures/into.t ...................... ok
t/foreign/Method-Signatures/invocant.t .................. ok
t/foreign/Method-Signatures/larna.t ..................... ok
t/foreign/Method-Signatures/method.t .................... ok
t/foreign/Method-Signatures/named.t ..................... ok
t/foreign/Method-Signatures/odd_number.t ................ ok
t/foreign/Method-Signatures/one_line.t .................. ok
t/foreign/Method-Signatures/optional.t .................. ok
t/foreign/Method-Signatures/paren_on_own_line.t ......... ok
t/foreign/Method-Signatures/paren_plus_open_block.t ..... ok
t/foreign/Method-Signatures/required.t .................. ok
t/foreign/Method-Signatures/slurpy.t .................... ok
t/foreign/Method-Signatures/syntax_errors.t ............. ok
t/foreign/Method-Signatures/too_many_args.t ............. ok
t/foreign/Method-Signatures/trailing_comma.t ............ ok
t/foreign/Method-Signatures/type_check.t ................ ok
t/foreign/Method-Signatures/typeload_moose.t ............ ok
t/foreign/Method-Signatures/typeload_notypes.t .......... ok
t/foreign/MooseX-Method-Signatures/attributes.t ......... ok
t/foreign/MooseX-Method-Signatures/caller.t ............. ok
t/foreign/MooseX-Method-Signatures/closure.t ............ ok
t/foreign/MooseX-Method-Signatures/errors.t ............. ok
t/foreign/MooseX-Method-Signatures/eval.t ............... ok
t/foreign/MooseX-Method-Signatures/list.t ............... ok
t/foreign/MooseX-Method-Signatures/named_defaults.t ..... ok
t/foreign/MooseX-Method-Signatures/no_signature.t ....... ok
t/foreign/MooseX-Method-Signatures/precedence.t ......... ok
t/foreign/MooseX-Method-Signatures/sigs-optional.t ...... ok
t/foreign/MooseX-Method-Signatures/too_many_args.t ...... ok
t/foreign/MooseX-Method-Signatures/type_alias.t ......... ok
t/foreign/MooseX-Method-Signatures/types.t .............. ok
t/foreign/MooseX-Method-Signatures/undef_method_arg.t ... ok
t/foreign/MooseX-Method-Signatures/undef_method_arg2.t .. ok
t/foreign/perl/signatures.t ............................. ok
t/foreign/signatures/anon.t ............................. ok
t/foreign/signatures/basic.t ............................ ok
t/foreign/signatures/eval.t ............................. ok
t/foreign/signatures/proto.t ............................ ok
t/foreign/signatures/weird.t ............................ ok
t/gorn.t ................................................ ok
t/hueg.t ................................................ ok
t/imports.t ............................................. ok
t/info.t ................................................ ok
t/install.t ............................................. ok
t/invocant.t ............................................ ok
t/lexical.t ............................................. ok
Can't locate loadable object for module Hash::Util in @INC (@INC contains: /home/tkloczko/rpmbuild/BUILD/Function-Parameters-2.001003/blib/lib /home/tkloczko/rpmbuild/BUILD/Function-Parameters-2.001003/blib/arch /usr/local/lib64/perl5/5.32 /usr/local/share/perl5/5.32 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at /usr/lib64/perl5/Hash/Util.pm line 48.
BEGIN failed--compilation aborted at /usr/lib64/perl5/Hash/Util.pm line 48.
Compilation failed in require at t/lifetime.t line 11.
BEGIN failed--compilation aborted at t/lifetime.t line 11.
# Looks like your test exited with 2 before it could output anything.
t/lifetime.t ............................................
Dubious, test returned 2 (wstat 512, 0x200)
Failed 12/12 subtests
t/lineno-torture.t ...................................... ok
t/lineno.t .............................................. ok
t/method_cache.t ........................................ ok
t/method_runtime.t ...................................... ok
t/name.t ................................................ ok
t/named_params.t ........................................ ok
t/precedence.t .......................................... ok
t/prototype.t ........................................... ok
t/recursion.t ........................................... ok
t/regress.t ............................................. ok
t/rename.t .............................................. ok
t/strict.t .............................................. ok
t/threads.t ............................................. ok
t/threads2.t ............................................ ok
t/types_auto.t .......................................... ok
t/types_caller.t ........................................ ok
t/types_custom.t ........................................ ok
t/types_custom_2.t ...................................... ok
t/types_custom_3.t ...................................... ok
t/types_custom_4.t ...................................... ok
t/types_moose.t ......................................... ok
t/types_moose_2.t ....................................... ok
t/types_moose_3.t ....................................... ok
t/types_moosex.t ........................................ ok
t/types_moosex_2.t ...................................... ok
t/types_msg.t ........................................... ok
t/types_parse.t ......................................... ok
t/unicode.t ............................................. ok
t/unicode2.t ............................................ ok

Test Summary Report
-------------------
t/lifetime.t                                          (Wstat: 512 Tests: 0 Failed: 0)
  Non-zero exit status: 2
  Parse errors: Bad plan.  You planned 12 tests but ran 0.
Files=120, Tests=2781, 13 wallclock secs ( 0.79 usr  0.72 sys +  7.90 cusr  4.03 csys = 13.44 CPU)
Result: FAIL
Failed 1/120 test programs. 0/2781 subtests failed.
make: *** [Makefile:1056: test_dynamic] Error 255

Method::Signatures support

I just came across this module and it basically solves the architectural problems with Method::Signatures. I think it's superior and would like to make a fully compatible wrapper. There's some missing syntax needed to bridge the gap.

These are the easy ones.

  • $foo? equivalent to $foo=
  • $foo! ($foo is required)
  • ... (ignores the rest of the arguments)
  • @_ (ignores the rest of the arguments)
  • func foo is equivalent to fun foo()
  • Named parameters are optional (unless made required with !)
  • //= is like = but it applies the default if the argument is passed in but undefined.

These are the not so easy ones (and fortunately pretty rarely used)

  • \@foo for aliasing (which turned out to be problematic)
  • where for value constraints (kinda redundant with types)
  • when for when the default should be applied
  • is for per parameter traits

It would be great if there were options to turn these on. The C parts are beyond my abilities, but if the easy ones were added I could write a compatibility wrapper between Method::Signatures and Function::Parameters.

Internal error in %^H with Sub::Quote and 2.001001

The following code causes an internal error in 2.001001

use Function::Parameters    qw( :strict );
use Sub::Quote              qw( quote_sub );

my $subref = quote_sub 'print "Hello, world!\n"';
$subref->();

The error is

Eval went very, very wrong:

 1: {
 2:   my $_UNQUOTED = ${$_[1]->{"\$_UNQUOTED"}};
 3:   my $_QUOTED = ${$_[1]->{"\$_QUOTED"}};
 4:   package main;
 5:   $$_UNQUOTED = sub {
 6:   ($_QUOTED,$_UNQUOTED) if 0;
 7: # BEGIN quote_sub PRELUDE
 8: package main;
 9: BEGIN {
10:   $^H = 131328;
11:   ${^WARNING_BITS} = undef();
12:   %^H = (
13:     "Function::Parameters/config" => "HASH(0x7fe6e98a9268)",
14:   );
15: }
16: # END quote_sub PRELUDE
17: print "Hello, world!\n"  };
18: }
19: 1;


Function::Parameters: internal error: $^H{'Function::Parameters/config'} not a hashref: HASH(0x7fe6e98a9268) at (eval 6) line 17.
 at test.pl line 5.

The error is not present in 2.000007

If I remove :strict and just have use Function::Parameters qw( ); it works.

Support Multiple Shifted Args (for method modifiers)

It would be nice if F::P offered a shortcut for working with Moose's around modifier, e.g.:

package My::FP;
use Function::Parameters;
sub import {
    Function::Parameters->import({
        ...
        decorator => { shift => [qw($orig $self)], ... },
    });
}

package Some::Role;
use Moose::Role;
use My::FP;
around some_sub => decorator (@args) {
    # $orig *and* $self already shifted off
};

(Right now you're only able to shift off a single argument.)

Function::Parameters::info does not get default values of optional arguments

Looks like now it can get only the arguments names, but not defualt values in case of optional argument. I would be interested in having that feature. For example, it can be used to generate from a function a string for its complete function signature, which can be used in automatic generating the function's doc POD, useful in mid-to-large scale projects.

Function::Parameters interferes with true

CC: @chocolateboy

I found a strange interaction between Function::Parameters and true.pm.

# Foo.pm
package Foo;

use Function::Parameters;
use true;

fun foo() {}

If I load Foo.pm it's fine. But if I load it in a for loop...

$ perl -I ~/tmp/ -we 'for(0..1) { require Foo }'
Foo.pm did not return a true value at -e line 1.

That is very peculiar. Load order of Function::Parameters vs true does not matter. If I change fun foo to sub foo true.pm works again. If I call foo at the end of Foo.pm it works again, despite returning false.

I guess either Function::Parameters is doing something to the opcodes that true isn't expecting, or true is doing something naughty.

Add ""=

Similar to #10, it has the same rationale but I'm doing this in a separate issue since it requires making up new syntax.

The third common reason to apply a default is for an empty string. ||= can't be used because "0" would be valid. ""= would be equivalent to...

$arg = "default" if !defined($arg) or !length($arg);

Is there any configuration setting to restore optional parameter lists in v2?

Hello,

We use Function::Parameters quite extensively at $work and have lots of instances where we use the method keyword without a parameter list.

eg.

has something => (
   is => 'lazy',
   builder => method { return $self->foo },
);

This code all breaks with version 2.

Is there some sort of configuration option we can use to make that syntax work again?

Thanks

Doesn't work with clang

01b1101 introduced some compiler options which do not work with clang (the default OS X compiler).

$ perl Makefile.PL 
Checking if your kit is complete...
Looks good
Generating a Unix-style Makefile
Writing Makefile for Function::Parameters
Writing MYMETA.yml and MYMETA.json
Windhund:Function-Parameters schwern$ make
cp lib/Function/Parameters/Info.pm blib/lib/Function/Parameters/Info.pm
cp lib/Function/Parameters.pm blib/lib/Function/Parameters.pm
Running Mkbootstrap for Function::Parameters ()
chmod 644 "Parameters.bs"
"/Users/schwern/perl5/perlbrew/perls/perl-5.18.1-thread/bin/perl" "/Users/schwern/perl5/perlbrew/perls/perl-5.18.1-thread/lib/site_perl/5.18.1/ExtUtils/xsubpp"  -typemap "/Users/schwern/perl5/perlbrew/perls/perl-5.18.1-thread/lib/5.18.1/ExtUtils/typemap"  Parameters.xs > Parameters.xsc && mv Parameters.xsc Parameters.c
cc -c   -fno-common -DPERL_DARWIN -fno-strict-aliasing -pipe -fstack-protector -I/opt/local/include -DDEVEL -fsanitize=address -fsanitize=undefined -O3   -DVERSION=\"1.0603_02\" -DXS_VERSION=\"1.0603_02\"  "-I/Users/schwern/perl5/perlbrew/perls/perl-5.18.1-thread/lib/5.18.1/darwin-thread-multi-2level/CORE"   Parameters.c
clang: error: unsupported argument 'undefined' to option 'fsanitize='
clang: error: unsupported argument 'address' to option 'fsanitize='
make: *** [Parameters.o] Error 1

Support array defaults

$ perl -wle 'use Function::Parameters qw(:strict);  method foo(@bar = (1,2,3)) {}  main->foo()'
In method foo: array @bar can't have a default value at -e line 1.

I don't see why not. Is this an implementation or design issue?

Hints hash should not store references

This was discussed already on RT:

But I think it worth giving this some visibility there.
It's a bad idea to store references in the Hash Hint a.k.a. %^H

A quick grep show that both the .pm and .xs code need some fixup

Changes:32:          - rewrite pragma implementation and the way %^H is used
Parameters.xs:2172:            croak("%s: internal error: $^H{'%s'} not a hashref: %"SVf, MY_PKG, HINTK_CONFIG, SVfARG(sv));
Parameters.xs:2182:            croak("%s: internal error: $^H{'%s'}{'%.*s'} not a hashref: %"SVf, MY_PKG, HINTK_CONFIG, (int)kw_len, kw_ptr, SVfARG(sv));
Parameters.xs:2205:        croak("%s: internal error: $^H{'%s'}{'%.*s'}{'%s'} not set", MY_PKG, HINTK_CONFIG, (int)kw_len, kw_ptr, HINTSK_ ## NAME); \
Parameters.xs:2218:            croak("%s: internal error: $^H{'%s'}{'%.*s'}{'%s'} not a coderef: %"SVf, MY_PKG, HINTK_CONFIG, (int)kw_len, kw_ptr, HINTSK_REIFY, SVfARG(sv));
Parameters.xs:2234:                    croak("%s: internal error: $^H{'%s'}{'%.*s'}{'%s'}: expected '$', found '%.*s'", MY_PKG, HINTK_CONFIG, (int)kw_len, kw_ptr, HINTSK_SHIFT, (int)(sv_p_end - p), p);
Parameters.xs:2238:                    croak("%s: internal error: $^H{'%s'}{'%.*s'}{'%s'}: expected idfirst, found '%.*s'", MY_PKG, HINTK_CONFIG, (int)kw_len, kw_ptr, HINTSK_SHIFT, (int)(sv_p_end - p), p);
Parameters.xs:2246:                    croak("%s: internal error: $^H{'%s'}{'%.*s'}{'%s'}: can't use global $_ as a parameter", MY_PKG, HINTK_CONFIG, (int)kw_len, kw_ptr, HINTSK_SHIFT);
Parameters.xs:2252:                            croak("%s: internal error: $^H{'%s'}{'%.*s'}{'%s'}: %"SVf" can't appear twice", MY_PKG, HINTK_CONFIG, (int)kw_len, kw_ptr, HINTSK_SHIFT, SVfARG((*ppspec)->shift.data[i].name));
Parameters.xs:2269:                            croak("%s: internal error: $^H{'%s'}{'%.*s'}{'%s'} not an arrayref: %"SVf, MY_PKG, HINTK_CONFIG, (int)kw_len, kw_ptr, HINTSK_SHIF2, SVfARG(sv));
Parameters.xs:2274:                        croak("%s: internal error: $^H{'%s'}{'%.*s'}{'%s'}: tix [%ld] out of range [%ld]", MY_PKG, HINTK_CONFIG, (int)kw_len, kw_ptr, HINTSK_SHIFT, (long)tix, (long)(av_len(shift_types) + 1));
Parameters.xs:2278:                        croak("%s: internal error: $^H{'%s'}{'%.*s'}{'%s'}: tix [%ld] doesn't exist", MY_PKG, HINTK_CONFIG, (int)kw_len, kw_ptr, HINTSK_SHIFT, (long)tix);
Parameters.xs:2282:                        croak("%s: internal error: $^H{'%s'}{'%.*s'}{'%s'}: tix [%ld] is not an object (%"SVf")", MY_PKG, HINTK_CONFIG, (int)kw_len, kw_ptr, HINTSK_SHIFT, (long)tix, SVfARG(type));
Parameters.xs:2289:                        croak("%s: internal error: $^H{'%s'}{'%.*s'}{'%s'}: expected ' ', found '%.*s'", MY_PKG, HINTK_CONFIG, (int)kw_len, kw_ptr, HINTSK_SHIFT, (int)(sv_p_end - p), p);
lib/Function/Parameters.pm:351:    my %config = %{$^H{+HINTK_CONFIG} // {}};
lib/Function/Parameters.pm:378:    $^H{+HINTK_CONFIG} = \%config;
lib/Function/Parameters.pm:385:        delete $^H{+HINTK_CONFIG};
lib/Function/Parameters.pm:389:    my %config = %{$^H{+HINTK_CONFIG}};
lib/Function/Parameters.pm:391:    $^H{+HINTK_CONFIG} = \%config;

It appears that this is the only CPAN module to store HINTK_CONFIG there so this should be safe, to move it to a better location.

https://grep.metacpan.org/search?size=20&q=HINTK_CONFIG&qd=&qft=

Maybe a GV in Function::Parameters itself?

Possible to use class name as a type name?

In porting over a codebase from Method::Signatures, I am dealing with a lot of methods that were using class names in the parameter lists. For example:

use Function::Parameters;
use URI;
use Types::Standard qw(ArrayRef);
method foo(URI $uri) { ... }   # Undefined type name error
method foobar(ArrayRef[URI] $uris) { ... }  # missing type name after '[' error

This seems to not work with Function::Parameters, or, I have missed the way to get these working. Using Types::Standard I tried things such as:

use Types::Standard qw(InstanceOf ArrayRef);
method foo1(InstanceOf[URI] $uri) { ... }    # Undefined type name URI error
method foo2(InstanceOf['URI'] $uri) { ... }  # missing type name after '[' error
method foo3(ArrayRef[ InstanceOf[URI] ] $uris) { ... }    # Undefined type name URI error
method foo4(ArrayRef[ InstanceOf['URI'] ] $uris) { ... }  # missing type name after '[' error

So either I am missing how to get this to work, or, I need to drop the class type constraints altogether and just use something like:

method foo1($uri) { ... }
method foo2(ArrayRef $uris) { ... }

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.