Initialization of an object in Perl

So, I'm a little perl newb. Although I had something much more complicated, I suddenly ended up at the checkpoint and cannot understand that wtf does not match the code. I simplified it so much that it is just a very small piece of code.

Test.pl

package Test;

sub new {
  my ($class) = shift;
  my $self = {
    _attr => "asdfa"
  };
  bless $self, $class;
  return $self;
}
sub log {
  print "\nAccessed via class: ".$self->{_attr};
}

process.pl

#!/usr/bin/perl
do "Test.pl";
use strict;
use warnings;
use diagnostics;

my($test) = new Test();
$test->log;
print "\nAccessed via main: ".$test->{_attr};

I run process.pl and get the following output

Access through the class:
Access via main: asdfa

I also get a warning

Using an uninitialized value in concatenation (.) Or a line in Test.pl line 12 (# 1) (W uninitialized) The undefined value was used as if it had already been defined. This was interpreted as "" or 0, but it may have been a mistake. To suppress this warning, assign a specific value to your variables.

, , $self undefined. , . ?

+3
3

. $self, perl , :

sub log {
  my $self = shift;
  print "\nAccessed via class: ".$self->{_attr};
}

, , strict warnings , test.pl, , $self undefined , .

, package Test Test.pm, 1; , use Test; do "test.pl". Perl.

+6

, , .

  • , .pm not .pl
  • use do .
  • , .

, .

MyTest.pm:

package MyTest;  # Changed name to avoid name conflicts.
use strict;      # Always
use warnings;

sub new {
  my $class = shift;
  # Removed parens on $class, they put the assignment of shift 
  # result into list context (which had no effect on the result, 
  # but it is also unnecessary).

  my %defaults = ( attr => 'asdfa' );
  my %args = %defaults, @_;  
  # Assigns arguments and default values to %args, actual named 
  # args will override keys in defaults where they match;      

  my $self = {};      

  bless $self, $class;

  while( my ($attr, $value) = each %args ) {
    $self->$attr($value); # Initialize each attribute in named arg hash.
  }

  return $self;
}

sub attr {
    my $self = shift;
    if( @_ ) {
      $self->{_attr} = shift;
    }

    return $self->{attr}
}    

sub log {
  my $self = shift;  # Get invocant
  print "Accessed via class: ", $self->attr, "\n";  
}

process.pl

#!/usr/bin/perl
use strict;
use warnings;
use diagnostics;

use MyTest;

my $test = MyTest->new();  # Direct call of object constructor

$test->log;

print "Accessed via main: $test->{_attr}\n";  # Violating encapsulation 
                                              # is generally a bad idea.

, Moose. Moose - , Perl, .

"" Perl OOP, perldoc (perlboot, perltoot, perlobj, perlbot perltooc) . , , Perl - .

+3

:

sub log{
    my $self = shift;
    print "\nAccessed via class: ".$self->{_attr};
}
0

Source: https://habr.com/ru/post/1761948/


All Articles