• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 192
  • Last Modified:

Accessomg Method Via Instantiation or Statically

Hi,

I need some clarification on an issue I was presented with, need to make sure I know exactly what I'm discussing.

Say I have a module:

Foo::Bar and in this class we have a subroutine called "go"

How would I demonstrate the differentiation between instantiating the Foo::Bar module, then calling "go" or just calling "go" from a non-instantiated method (static)

I'm kinda new to perl so I apologize if this doesn't make the most sense.  Also, am I using the term "static" correctly?

Thanks
0
paulj1999
Asked:
paulj1999
  • 4
  • 2
2 Solutions
 
Adam314Commented:
Calling go:
    Foo::Bar::go();

Creating object, then calling:
    my $foobar = new Foo::Bar();
    $foobar->go();
0
 
paulj1999Author Commented:
so is Foo::Bar::go() a static instance then?
0
 
Adam314Commented:
Not sure what you mean by "static instance".

In the first case, the go function of the Foo::Bar module will be called, passing no parameters.

In the second case, the variable $foobar is a blessed reference of Foo::Bar.  The go function of the Foo::Bar module will be called, passing $foobar as the first parameter.

You could also do:
   Foo::Bar->go();
which would pass the class name 'Foo::Bar' as the first parameter when calling the go function.

0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
DropZoneCommented:
"Static" means different things in different contexts.  Furthermore, you seem to be confusing the term "instance" and "method".  These terms imply the use of object-oriented mechanisms in Perl.

In Perl, a module may define just a set of subroutines or code, or it may define classes.  I'm not sure how familiar you are with object-oriented concepts, so pardon if what follows seems basic.  In object-oriented programming, your code performs its work by manipulating and operating on "objects".  Objects are described by their classes, which are like templates of the structure of an object.  Classes are therefore the blueprints of objects, and an object is in turn concrete instance of a particular class.

Objects have "methods" which are functions or subroutines that perform the work that the object is intended to do.

In Perl, the object-oriented mechanism is more loose than in other languages, and is implemented using the standard syntax used for regular subroutines and packages.  There is no special directive that specifies whether a particular subroutine is a method of a class or not--they are all just subroutines within a package module, intended to be used by an instance of the class.

Therefore, there is nothing in the language that prevents you from calling a class' methods directly as a regular subroutine, instead of using an instance of the object.  The only difference is that the method will be executed without the context of the object--that is, all instance variables (properties and internal variables pertaining to a specific instance of an object) will not be available.

A class can also have "static" methods.  These are methods that do not require an instance, and that operate on the class as a whole.  Any variables that they use will apply globally to the entire module and all instances of the class.

Below is a simple example of calling an object method using the object and directly through the package.  It also shows what happens when calling a static method.

    -dZ.

#class Person
package Person;
 
# Default language.
my $language = 'English';
 
#constructor
sub new {
    my ($class) = @_;
    my $self = {
        _firstName => undef,
        _lastName  => undef
    };
    bless $self, $class;
    return $self;
}
 
# Method to set the First Name
sub firstName {
    my ( $self, $firstName ) = @_;
    $self->{_firstName} = $firstName if defined($firstName);
    return $self->{_firstName};
}
 
# Method to set the Last name
#accessor method for Person last name
sub lastName {
    my ( $self, $lastName ) = @_;
    $self->{_lastName} = $lastName if defined($lastName);
    return $self->{_lastName};
}
 
# Static method for Person's language
sub language {
    my $newlang = shift @_;
 
    # Check if we were called with an instance
    if (ref $newlang)
        {
        # if so, get the next parameter instead
        $newlang = shift;
        }
 
    $language = $newlang if (defined $newlang);
 
    return $language;
}
 
 
1;
 
#################
 
# From your code:
 
# Instantiate a new Person object.
# $man is a reference to a specific instance of Person.
# $woman is reference to a different instance of Person.
my $man   = new Person();
my $woman = new Person();
 
# Set the name of the Person objects
 
# Sets the First and Last names in the $man instance
$man->firstName('John');
$man->lastName('Dough');
 
# Sets the First and Last names in the $woman instance
$woman->firstName('Jane');
$woman->lastName('Doe');
 
# Prints: John Dough
print $man->firstName, " ", $man->lastName, "\n";
 
# Prints: Jane Doe
print $woman->firstName, " ", $woman->lastName, "\n";
 
# Won't do anything, since the method expects an instance.
print Person::firstName('foo');
 
# We can set the language calling the method directly,
# since it is "static" and not expecting an instance.
Person::language('French');
 
# Displays "French"
print Person::language(), "\n";
 
# We can also call the static method using an instance
# since it was made to ignore the instance:
$man->language('German');
 
# Prints "German", since the language applies to all instances.
print $woman->language(), "\n";

Open in new window

0
 
Adam314Commented:
Some of your examples demonstrate very poor code....

>># Won't do anything, since the method expects an instance.
>>print Person::firstName('foo');
Not true... it is not that it "does nothing".  It attempts to use 'foo' (a string scalar) as a hash reference, and set the _firstName key of this.  If you have strict refs turned on, you'd get an error about this.

>>sub language {...}
If called as an object method, you throw away the object, and set the value of the package variable $language.  You'd not get what you expect.  Try this code:
    $man->language('German');
    print "man->language=",$man->language,"\n";    #you get German
    $woman->language('Spanish');
    print "man->language=",$man->language,"\n";    #you get Spanish!!   :(
If you want to have package defaults, you should copy these values to the instance objects upon creation.  In your examples, $language isn't a default - it is a package variable, and with your language subroutine, the ONLY value for ALL objects.
0
 
DropZoneCommented:
I'm sorry that you feel that way, but the code was a quick and dirty example to illustrate what happens when calling instance methods directly through the package, which is not proper.

Second, the "language" method does exactly what I was trying to illustrate: a static method that changes a package variable, which is global to all instances--not a default.  If you see my sample code, I set "German" for the $man instance and then illustrated that it was at the package level by displaying that value when calling it using the $woman instance.

Perhaps it was a poor example, but did its purpose: it shows that calling an instance method directly does not get you what you want, and that a static method is different than an instance method, because it does not operate on an instance, but at the class or package level.

My intention wasn't to show good techniques on how to build object oriented applications in Perl, but to illustrate the difference between a static method and an instance method in Perl.  This is what I thought was the question.  Whether it is a good idea to use static methods to set package level variables, in my opinion, is outside the scope of the question.

     -dZ.
0
 
Adam314Commented:
I must have misunderstood what you were trying to show...
0

Featured Post

Prep for the ITIL® Foundation Certification Exam

December’s Course of the Month is now available! Enroll to learn ITIL® Foundation best practices for delivering IT services effectively and efficiently.

  • 4
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now