-2
use Person;

print(" object creation ");
my $object = new Person( "Mohammad", "Saleem", 23234345);

print (" here after");
allthis();

sub allthis()
{
  print(  $object->getFirstName() );
}

if(1)
{ 
  print(" object creation ");
  my $object = new Person( "Mohammad", "Saleem", 23234345);
  allthis();

  sub allthis()
  {
    print($object->getFirstName());
  }
}

Person is defined here:

package Person;

sub new
{
  my $class = shift;
  my $self = {
    _firstName => shift,
    _lastName  => shift,
    _ssn       => shift,
  };
  print "First Name is $self->{_firstName}\n";
  print "Last Name is $self->{_lastName}\n";                                                  
  print "SSN is $self->{_ssn}\n";
  bless $self, $class;
  return $self;
}

sub setFirstName {
  my ( $self, $firstName ) = @_;
  $self->{_firstName} = $firstName if defined($firstName);
  return $self->{_firstName};
}

sub getFirstName {
  my( $self ) = @_;
  return $self->{_firstName};
}
1;

This leads to

Error : Can't call method "getFirstName" on an undefined value at check2.pl line 22.

The error won't occur in two cases:

  1. declare the variables as our.
    example: our object;

  2. rename one of the function names:
    allthis to allthis1

Can any one explain the reason?

eckes
  • 56,506
  • 25
  • 151
  • 189
seeram
  • 11
  • 3

3 Answers3

2

In Perl, all named subroutines are globally scoped. You can't have two subroutines with the same name existing in two different scopes like that. Thus, the second definition of allthis() overrides the first one. You never use the first allthis() sub.

Further, because subroutines have access to the lexical variables of wherever they were defined, your first call to allthis() attempts to access the second $object; however, this hasn't been defined yet.

dan1111
  • 6,264
  • 2
  • 15
  • 29
  • Also, I should have mentioned that switching to an `our` declaration means that you would only have one copy of `$object`. It would act as a global variable within the scope of the current package, thus removing the error. However, in that case a second use of `our` within the `if` statement would be meaningless, as you are merely referring to an already existing variable. – dan1111 Aug 09 '12 at 13:50
1

First of all, use strict and use warnings. Always. Each and every single time.

Because if you had, you would've received a warning that you were redefining main::allthis(). So, don't do that.

This code should get you what you need:

use strict;
use warnings;
use Person;

print(" object creation ");
my $object = new Person( "Mohammad", "Saleem", 23234345);


sub allthis() #have to define after $object is created
{
print($object->getFirstName());
}

print (" here after");
allthis();

print(" object creation ");
$object = new Person( "Mohammad", "Saleem", 23234345);
allthis();

However, I'd consider whether it is necessary to use $object as a global variable (with respect to allthis(), and instead have your subroutine take an argument:

sub allthis
{
  my $object = shift;
  print $object->getFirstName();
}

Then, you'd call it via allthis($object);.

  • thanks for the answer. i know that we should use strict and warrnings. can please tell me, why it works when i define the variables "our". – seeram Aug 09 '12 at 06:21
  • By this post, i am not expecting coding guidelines.... I am expecting an answer for the question, why the program work fine when i declare the variable "our $object = new Person( "Mohammad", "Saleem", 23234345);". so that i know, how perl actually works. – seeram Aug 09 '12 at 06:28
  • because then the first our $object and the second refer to the same variable. only the second allthis function is ever called, and it binds to the second $object declaration; with my, that is a different $object than was set before the first allthis call. – ysth Aug 09 '12 at 06:38
  • but you hardly ever need to worry about how perl does variable binding in more complex cases; just pass what you need into functions instead of referring to outside variables. – ysth Aug 09 '12 at 06:41
  • @ysth: thanks for the reply. it make sense. but i dont understood, with "my" it goes out of the scope. can you please elaborate more or point me to some document which talks more on this. – seeram Aug 09 '12 at 07:00
  • http://stackoverflow.com/questions/845060/what-is-the-difference-between-my-and-our-in-perl –  Aug 09 '12 at 07:31
  • seeram: named functions are global; you can only have one at a time. when the code is compiled, the second allthis replaces the first. The second allthis is in the lexical scope of the second $object lexical variable, and that hasn't yet been set at the time it is first called – ysth Aug 09 '12 at 19:55
0

Here:

use strict;
use warnings;

use Person;

print(" object creation\n");
my $object = new Person( "Mohammad", "Saleem", 23234345 );


sub allthis() {
    print( $object->getFirstName() . "\n");
}

print(" here after\n");
allthis();



print(" object creation\n");

$object = new Person( "Mohammad", "Saleem", 23234345 );

allthis();

Output:

 object creation First Name is Mohammad
Last Name is Saleem
SSN is 23234345
 here afterMohammad
 object creation First Name is Mohammad
Last Name is Saleem
SSN is 23234345
Mohammad
Hameed
  • 2,094
  • 1
  • 18
  • 29
  • Thanks for the reply. but i dont want to change the code. i mentioned two point in the post. when it passes and fails... so can please answer to those questions. i am not searching for code changes.. i know what to do , to make my piece of code work. but my intension of the post it to get answer for the questions of those two poins i mentioned in the post. – seeram Aug 09 '12 at 06:34