bkv2k has asked for the wisdom of the Perl Monks concerning the following question:

I accidentally did the following and was surprised that it worked. Can anyone give me a clue why? In it's own file: (MyTest.pm)
package MyTest; use warnings; use strict; sub new { my ($class) = @_; $class = ref( $class ) || $class; my $self = {}; bless( $self, $class ); return $self; } sub display { my ($self) = @_; print "\nWow! It worked.\n\n"; } sub test { my ($self) = @_; display(); } return 1;
In a separate file: (my_test.pl)
#!/usr/bin/perl use warnings; use strict; use MyTest; my $tst = MyTest->new(); $tst->test();
Shouldn't this havd crashed when display() is called in sub test() instead of $self->display()?

Replies are listed 'Best First'.
Re: Object Method Call
by moritz (Cardinal) on Jul 26, 2009 at 16:45 UTC
    It should not have crashed; sub display { ... } is a valid subroutine declaration, and display() is a valid sub call.

    The fact that you think of display as being a method and not a sub is not known to perl.

    In Perl 5 the question of whether something is treated as a method or a sub is determined by the caller, not by a declaration.

Re: Object Method Call
by dreadpiratepeter (Priest) on Jul 26, 2009 at 16:48 UTC
    In addition to what moritz said, you will notice the problem if you attempt to use $self in display. Since you called it as a sub rather than a method $self will be undefined.


    -pete
    "Worry is like a rocking chair. It gives you something to do, but it doesn't get you anywhere."
      ... you will notice the problem if you attempt to use $self in display.
      However, if the call (from within the  test() subroutine) had been
          display($self);
      there would have been no problem: this would have emulated the effect of the  -> operator and a
          $self->display;
      call.

      This just reinforces moritz and dreadpiratepeter's point that Perl does not know what's in your mind, only in your code.

        How could perl possibly know what's in _my_ mind ... all too frequently, I've absolutely no idea - as I capably demonstrate thro' my rambling postings here :-D

        Sits back and wonders whether the telepathy engine in perl6 will be more than a figment of someones' fevered imagination ;-|

        </silliness>

        A user level that continues to overstate my experience :-))
        Thanks all for the help!

        But there is a slightly difference between display($self) and $self->display(), when a class XY inherits from MyTest and implements it's own display() method. display($self) calls MyTest::display() even when invoked on an instance of XY, whereas $self->display() calls XY::display() when invoked on an instance of XY. So, one could say that display($self) breaks inheritance. This is often bad, but sometimes, it can be a useful trick.

        Alexander

        --
        Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
Re: Object Method Call
by ikegami (Patriarch) on Jul 27, 2009 at 00:23 UTC

    In Perl 5, the difference between a function, a class method, a non-virtual method and a virtual method is entirely in the call.
    Function callfoo(...)
    Class method call$class->foo(...)
    Non-virtual method call (Hardcoded)$o->Class::foo(...)
    Non-virtual method call (Dynamic)my $method = __PACKAGE__->can('foo');
    $o->$method(...)
    Virtual method call$o->foo(...)

    Needless to say, people only create virtual instance methods in Perl.

    You're expected to use the correct calling convention for a given sub.