Perl Module Method Calls: Can't call method “X” on an undefined value at ${SOMEFILE} line ${SOMELINE}

前端 未结 3 2023
时光取名叫无心
时光取名叫无心 2020-12-16 06:34

All over the place, especially in DBI, I see this message come up all the time. It\'s confusing, because the first thing that comes to mind is that the arguments I\'m passin

3条回答
  •  余生分开走
    2020-12-16 07:07

    You're conflating several different ways to handle modules and objects - and ending up with one that doesn't work.

    Here are four approaches that do work:

    1/ My::Module is a library. trim is not exported.

    $ cat My/Module.pm 
    package My::Module;
    
    use strict;
    use warnings;
    
    sub trim {
      my $str = shift;
    
      $str =~ s{ \A \s+ }{}xms; # remove space from front of string
      $str =~ s{ \s+ \z }{}xms; # remove space from end of string
      return $str;
    }
    
    1;
    $ cat test 
    #!/usr/bin/perl
    
    use strict;
    use warnings;
    
    use My::Module;
    
    # Note: No $ and :: not ->
    print My::Module::trim( " \t hello world\t \t" );
    

    2/ My::Module is a library. trim is exported.

    $ cat My/Module.pm 
    package My::Module;
    
    use strict;
    use warnings;
    
    use Exporter;
    our @ISA    = qw(Exporter);
    our @EXPORT = qw(trim);
    
    sub trim {
      my $str = shift;
    
      $str =~ s{ \A \s+ }{}xms; # remove space from front of string
      $str =~ s{ \s+ \z }{}xms; # remove space from end of string
      return $str;
    }
    
    1;
    $ cat test 
    #!/usr/bin/perl
    
    use strict;
    use warnings;
    
    use My::Module;
    
    print trim( " \t hello world\t \t" );
    

    3/ MyModule is a class. trim is a class method.

    $ cat My/Module.pm 
    package My::Module;
    
    use strict;
    use warnings;
    
    sub trim {
      # Note class name passed as first argument
      my $class = shift;
      my $str = shift;
    
      $str =~ s{ \A \s+ }{}xms; # remove space from front of string
      $str =~ s{ \s+ \z }{}xms; # remove space from end of string
      return $str;
    }
    
    1;
    $ cat test 
    #!/usr/bin/perl
    
    use strict;
    use warnings;
    
    use My::Module;
    
    # Note: Not $ and -> not ::
    print My::Module->trim( " \t hello world\t \t" );
    

    4/ MyModule is a class, trim is an object method.

    $ cat My/Module.pm 
    package My::Module;
    
    use strict;
    use warnings;
    
    # Need a constructor (but this one does nothing useful)
    sub new {
      my $class = shift;
    
      return bless {}, $class;
    }
    
    sub trim {
      # Note: Object method is passed an object (which is ignored here)
      my $self = shift;
      my $str = shift;
    
      $str =~ s{ \A \s+ }{}xms; # remove space from front of string
      $str =~ s{ \s+ \z }{}xms; # remove space from end of string
      return $str;
    }
    
    1;
    $ cat test 
    #!/usr/bin/perl
    
    use strict;
    use warnings;
    
    use My::Module;
    
    my $trimmer = My::Module->new;
    
    print $trimmer->trim( " \t hello world\t \t" );
    

    I think that you were trying for option 1. In this case, I think I'd recommend option 2.

    And to answer your final question. You are getting that error because you are trying to call a method on a variable ($My::Module) which is undefined.

提交回复
热议问题