2013-12-12 5 views
12

При изучении других языков часто существует разница между методом класса и методом объекта.Метод и метод класса класса Perl

Я знаю, что в Perl класс слабый. Есть ли разница между методом класса и методом объекта?

Я знаю, что наиболее часто используемым методом класса может быть метод класса new. В Perl я могу вызвать все методы с именем пакета, но не с объектом пакета. Почему это?

+0

Я просто хочу знать, почему имя использование пакета можно назвать все методы в пакете, есть какой-либо метод объекта, поэтому пакет не может назвать это непосредственно – JackXu

ответ

12

The perlobj man page полезно здесь:

При вызове метода, вещь на левой стороне стрелки передается в качестве первого аргумента метода. Это означает, что когда мы вызываем Critter->new(), метод new() принимает в качестве первого аргумента строку "Critter". Когда мы вызываем $fred->speak(), переменная $fred передается как первый аргумент speak().

Другими словами, Perl не делает резкое различие между методами класса и методами экземпляра. Они отличаются тем, что передается как первый аргумент метода, и если некоторые методы фактически не заботятся о том, что передается в качестве первого аргумента, тогда вы можете обмануть и называть их «неправильным» способом.

Perl не имеет значения. Обычно этого не происходит.

+0

так как это означает, что, когда метод не заботится о первый параметр, эффективность вызова класса и вызова метода одинаковы? – JackXu

+0

Я считаю, что это правильно. В большинстве случаев вам не удастся это избежать: методы большинства экземпляров являются экземплярами, потому что они делают что-то с состоянием объекта, к которому они привязаны. Но иногда вам повезет, и это не имеет значения. –

+1

Я считаю, что это вводящий в заблуждение ответ. Perl примет либо благословенную ссылку, либо просто строку в качестве получателя вызова метода. Больше ничего не будет.Кроме того, вызов метода класса не менее быстрый, чем вызов метода объекта: Perl должен искать имя класса для метода объекта, тогда как имя класса передается ему для вызова метода класса. – Borodin

5

@ Ответ qwrrty - это хорошее объяснение ситуации, но из комментариев у меня создается впечатление, что даже если Perl делает небольшое различие между методами класса и объекта, @JackXu будет как такое различие.

Если вы хотите сделать такое различие, то решение должно проверить $_[0], чтобы увидеть, является ли это объектом или строкой, и вести себя соответствующим образом (например, вызывать исключение, если метод объекта вызывается с именем класса в качестве первый параметр).

Существуют различные модули метод подписи, доступных на CPAN, которые делают это тупо легко сделать, вдоль линий:

package Foo; 
method xxx (Object $self: Int $x) { 
    ...; 
} 

Foo->xxx(1); # throws an error because "Foo" is not an object 

я собираюсь сутенер мое собственное решение для такого рода вещи - Moops, который не только дает вам сигнатуры методов, но и ключевые слова для class, role и т. д. Частная причина для сутенерства здесь заключается в том, что благодаря поддержке «нескольких методов» вы даже можете создать метод класса и метод объекта с тем же назовите друг друга!

use Moops; 

class Foo 
{ 
    multi method xxx (ClassName $class: Int $x) { 
    say "CLASS METHOD - value $x"; 
    } 
    multi method xxx (Object $self: Int $x) { 
    say "OBJECT METHOD - value $x"; 
    } 
} 

Foo->xxx(1); 

my $foo = Foo->new; 
$foo->xxx(2); 
Смежные вопросы