LanX has asked for the wisdom of the Perl Monks concerning the following question:

I got the requirement to check at compile time if a method call is valid.

Is there already any project on CPAN which parses the optree in the CHECK phase?

please refer to this demo code

package TEST; # The Class sub new { bless {}, $_[0] } sub bla { warn "Bla called" } package main; CHECK { warn B::Deparse->new()->coderef2text(\&tst); } use strict; use warnings; use Data::Dump qw/pp dd/; use B::Deparse; sub tst { my TEST $x; # Typing $x = TEST->new() ; $x->blo(); # Typo } tst();

output

{ use warnings; use strict; my TEST $x; $x = 'TEST'->new; $x->blo; } at d:/exp/deparse_type.pl line 11. Can't locate object method "blo" via package "TEST" at d:/exp/deparse_ +type.pl line 23.

the wrong method call ->blo is only caught at run-time yet while B::Deparse shows that all informations are already available in the op-tree after voluntary typing.

Please spare me with comments like "This is unperlish", my colleagues are propagating a far worse solution with exported constants to catch typos.

 $x->$blo

$blo would be caught by strict because it's not predefined like $bla="bla" .

Cheers Rolf
(addicted to the Perl Programming Language :)
Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

Replies are listed 'Best First'.
Re: compiletime checking of valid method calls
by choroba (Cardinal) on Apr 08, 2019 at 16:03 UTC
    I'm sorry not to comply with your plea, but...

    What if the code adds new subroutines at runtime?

    Why do you need it? It seems you picked a wrong language for the requirements.

    map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
      > What if the code adds new subroutines at runtime?

      My objective is to be better than the export constant solutions.

      And I'm only seeing this "solution" activated in the test/dev phase.*

      So if a method is added at runtime it would need to be "pre-registered" at compile time, much like a constant would need to be declared at compile time.³

      We don't add methods at compile time, and our "use" of OO is probably best described as weird QQ.²

      DISCLAIMER: I can't choose my colleagues and bosses and I don't have any alternative workplaces at disposal yet.

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

      *) in other words it's not weirder than using PPI for this in a .t test.

      ²) My colleagues don't know how to add methods at compile time yet.

      ³) or checking would be deactivated by omitting the type information.

Re: compiletime checking of valid method calls
by Veltro (Hermit) on Apr 08, 2019 at 22:22 UTC

    Figured maybe it was possible to use fields, but only got it to work for functions, not methods... Strangely enough the error occurs at line 8.

    package BOGUS ; use fields qw( new ) ; package TEST ; my BOGUS $b ; $b = fields::new("BOGUS") ; @{$b}{keys %TEST::} = @TEST::{keys %TEST::} ; sub new { my $class = shift ; my TEST $self = {} ; bless $self, $class ; print "Runtime!\n" ; bloeb() ; return $self ; } package main ; use strict ; use warnings ; sub tst { my TEST $x ; $x = TEST->new() ; $x->blo() ; } tst() ;
      Many thanks! :)

      I have to admit that the fields pragma has always been one of the most obscure parts of Perl for me.

      From the documentation it's supposed to only limit hash access. From the synopsis:

      # this will generate a compile-time error my Foo $foo = Foo->new; $foo->{zap} = 24;

      There is no mention of restricting methods, as far as I can see.

      And the mainstream says that directly accessing attributes should be totally avoided and better be done via getter and setter methods. ( Well I know that this rule is mostly ignored in Python)

      I have problems imagining what for the fields pragma was introduced

      Edit

      Oh I think I understand now what you are trying to do, limiting the hash access to the STASH of the class?

      That's ... Courageous! :)

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery FootballPerl is like chess, only without the dice