I’m a Java/C/C#/python coder who is attempting his first Perl script, and I have what is prob a Perl OOO 101 question: What is the syntax to access an object’s members when use strict
is required?
Let me speak Java for a moment. I have this little program, all in one class file:
class Dude{
public String name;
public Dude(String name){
this.name = name;
}
public void IntroduceYourself(){
System.out.println("Hi, I'm "+this.name);
}
}
public toy(){
Dude fred = new Dude("Fred");
fred.IntroduceYourself();
}
Output on my Ubuntu machine:
me@ubuntu01:~/$ java toy
Hi, I'm Fred
me@ubuntu01:~/$
What could be simpler? I create a Dude
object, then later call method Dude.IntroduceYourself()
, which accesses a class member.
Okay: I have to do the exact same thing, but now in Perl (v5.26.1). Again, use strict;
is required. Here’s my miserable attempt:
#!/usr/bin/perl
use warnings;
use strict;
# Define a "Dude" class
package Dude;
sub new
{
my $class = shift;
my $self = {
_name => shift,
};
bless $self, $class;
return $self;
}
sub IntroduceYourself
{
print("Hi, I'm $object->{name}n"); # Compilation Error here!
}
my $object = new Dude("Fred");
$object->IntroduceYourself();
Output on the same Ubuntu machine:
me@ubuntu01:~/$ ./toyPerl.pl
Global symbol "$Dude" requires explicit package name (did you forget to declare "my $Dude"?) at ./toyPerl.pl line 18.
Execution of ./toyPerl.pl aborted due to compilation errors.
me@ubuntu01:~/$
Ugh. I’ve been reading a few Perl tutorials, and I see examples on how to write that IntroduceYourself()
subroutine, but none with use strict
as a global directive. Can anyone see what I’m doing wrong?
Also: I’m really confused about what I’ll call "member functions" in Perl. In my Java example, Dude.IntroduceYourself()
was defined as a method of class Dude
. I intend (if possible) for IntroduceYourself()
to be a function of Object/Class Dude
in the Perl code. But its unclear to me how to define that. Am I misunderstanding how Perl objects handle member functions? Thank you.
2
Answers
See perlootut.
In OOP, the invocant (the value of the expression before the
.
/->
) is passed to the method as an argument. In Java, this argument is made available asthis
. In Perl, this argument is made available as a leading parameter.This means that
is equivalent to
And the method looks like this:
This doesn’t have to do with OO, just Perl’s normal
strict
behavior.strict
forces you to declare variables, like in other languages. Withoutstrict
, undeclared objects are globals.$object
is never declared, so it violates strict.To solve this,
$object
must be declared. Perl’sthis
is passed in as the first argument to a method. You need to get that argument. Perl calls this the "invocant". Typically it is called$self
.Perl doesn’t have object members like Java. A Perl object is just a reference. It doesn’t even need to be a hash reference.
$self->{key}
is just using a hash reference, so the key has to match.$self->{_name}
not$self->{name}
.You did it. A class is just a package. A method is just a subroutine in a package. The language does not make a distinction between subroutines and methods, nor between class and object methods. It’s just how you use them.
Perl’s OO is extremely basic. You get classes (via packages), multiple-inheritance (via @ISA), and methods (via subroutines with the invocant passed in) and that’s about it. No accessors, no public, no private, no members, not even
this
.If you want that, you have to write it yourself, or use an existing library. If you want all the bells and whistles and a full marching band, install Moose.
use strict
is not global, it is local to the current scope. The current scope is the whole file, but you can put it in a block.Things like
strict
andwarnings
are referred to as "pragmas".See "What’s the difference between dynamic and lexical (static) scoping? Between local() and my()?".