Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
638 views
in Technique[技术] by (71.8m points)

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

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 passing the function are set to undef (or something similar), but it's clearly not the case.

Given a module and a corresponding script...

Module: ./lib/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;
}

Script: ./test.pl

#!/usr/bin/perl

use strict;
use warnings;
use My::Module qw(trim);

print $My::Module->trim( "  hello world " );

I get back the error message

Can't call method "trim" on an undefined value at ./text.pl line 7.

Infact, if I call $My::Module->notamethod( "hello world" ); it gives a similar error.

What's wrong with the above script/module?

What is that error Can't call method “X” on an undefined value at ${SOMEFILE} line ${SOMELINE} really saying? Does this refer to the context of the method call (passed here to print), or the context of the arguments?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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( "  hello world " );

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( "  hello world " );

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( "  hello world " );

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( "  hello world " );

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...