Calling the Perl module method: it is not possible to call the "X" method in the undefined value in the string $ {SOMEFILE} $ {SOMELINE}

Everywhere, especially in DBI, I see that this message appears constantly. This is confusing because the first thing that comes to mind is that the arguments passed by the function are set to undef (or something similar), but this is clearly not the case.

For the module and 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( " \t hello world\t \t" ); 

I am returning an error message

It is not possible to call the trim method on an undefined value in a string. /text.pl 7.

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

What happened to the above script / module?

What is this error Can't call method "X" on an undefined value at ${SOMEFILE} line ${SOMELINE} really says? Does this relate to the method invocation context (passed here for printing) or the arguments context?

+6
function module perl dbi
source share
3 answers

This syntax looks for the object or class name in the variable $My::Module and calls its trim method, but this variable is undefined.

Instead, you just want to say print My::Module::trim( " \t hello world\t \t" ); to call the function My :: Module :: trim ().

From the usage line, it looks like you are trying to import trim () into a local package so that you can just call it without qualification My::Module:: , but your module does not look like it is configured to support export.

In your regular expressions, the / s and / m flags have no effect - they only change what., ^ And $ match are, and you don't use them.

+6
source share

You combine several methods of processing modules and objects - and end up not working.

Here are four approaches that 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 you were trying to choose option 1. In this case, I would recommend option 2.

And answer your last question. You get this error because you are trying to call a method on a variable ($ My :: Module), which is undefined.

+13
source share

This is how Perl does OO. The difference is how you call the methods.

This simply causes the sub to be truncated in the My :: Module package:

  My::Module::trim('foo') 

On the other hand,

  My::Module->trim('foo) 

automatically becomes a call to the trim element in the package My :: Module with the string "My :: Module" as the first argument. Objects work the same way:

  my $m = My::Module->new; # Corrected. Thanks for pointing this out. $m->trim('foo'); 

Included in the call to the same sub, but this time the reference to the object $ m is the first argument.

What are you trying to do:

 $My::Module->trim('foo'); 

This translates into dereferencing the variable $ My :: Module (which does not exist), so the error message "Cannot call method X with the value undefined" appears. If $ My :: Module was an actual object reference, this would result in a trim () call for that object with the reference as an implicit first argument.

Edit: both commentators are correct. This answer was originally intended to comment on the accepted answer. (Is there a way to fix this?)

Sorry for the confusion. I added a little more detailed information here, so I hope it becomes more clear how this relates to the original question (dereferencing the variable undefined).

-one
source share

All Articles