Анимация
JavaScript


Главная  Библионтека 

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 [ 151 ] 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242

Когда придет время косвенного вызова этого метода, напишите:

$fnref->(10, "fred"); и это даст правильный вызов метода:

$ob]->method(10, "fred");

Такое решение работает даже в том случае, если $оЬ находится вне области действия и потому является предпочтительным.

Ссылку на код, возвращаемую методом сап() класса UNIVERSAL, вероятно, не следует использовать для косвенного вызова методов. Нельзя быть уверенным в том, что она будет соответствовать правильному методу для объекта произвольного класса.

Например, следующий фрагмент крайне сомнителен:

$ob]->can(method name)->($obj target, ©arguments) if $ob] target->isa( ref $ob] );

Ссылка, возвращаемая сап, может и не соответствовать правильному методу для $оЬ]2. Вероятно, разумнее ограничиться проверкой метода сап() в логическом условии.

> Смотри также-

perlobj(iy, рецепт 11.8.

13.8. Определение принадлежности субкласса

Проблема

Требуется узнать, является ли объект экземпляром некоторого класса или одного из его субклассов. Например, надо выяснить, можно ли вызвать для объекта некоторый метод.

Решение

Воспользуйтесь методами специального класса UNIVERSAL:

$ob]->isa("HrrP::Message"); п Как метод объекта

HTTPResponse->isa("HTTP: iMessage"); tt Как метод класса

If ($ob]->can("method name")) { - } » Проверка метода

Комментарий

Для нас было бы очень удобно, чтобы все объекты в конечном счете происходили от общего базового класса. Тогда их можно было бы наделить общими методами, не дополняя по отдельности каждый массив @ISA. В действительности такая возможность существует. Хотя вы этого не видите, но Perl считает,



13.8. Определение принадлежности субкласса 471

что в конце @ISA находится один дополнительный элемент - пакет с именем UNIVERSAL.

В версии 5.003 класс UNIVERSAL не содержал ни одного стандартного метода, но вы могли занести в него все, что считали нужным. Однако в версии 5.004 UNIVERSAL уже содержит несколько методов. Они встроены непосредственно в двоичный файл Perl и потому на их загрузку не расходуется дополнительное время. К числу стандартных методов относятся isa, can и VERSION. Метод isa сообщает, «является ли» (is а) объект или класс чем-то другим, избавляя вас от необходимости самостоятельно просматривать иерархию:

$has io = $fd->isaCTO. :Handle"); $itza handle = 10 Socket->isaCTO Handle),

Также существует мнение, что обычно лучше попробовать вызвать метод. Считается, что явные проверки типов вроде показанной выше слишком ограничивают свободу действий.

Метод сап вызывается для объекта или класса и сообщает, соответствует ли его строковый аргумент допустимому имени метода для данного класса. Он возвращает ссылку на функцию данного метода:

$his print method = $ob]->can(as string),

Наконец, метод VERSION проверяет, содержит ли класс (или класс объекта) пакетную глобальную переменную $VERSION с достаточно высоким значением:

Some Module->VERSI0N(3.0): $his vers = $ob]->VERSION();

Тем не менее нам обычно не приходится вызывать VERSION самим. Вспомните: имена функций, записанные в верхнем регистре, означают, что функция вызывается Perl автоматически. В нашем случае это происходит, когда в программе встречается строка вида:

use Some Module 3 0;

Если вам захочется включить проверку версии в класс Person, описанный выше, добавьте в файл Person.pm следующий фрагмент:

use vars qw($VERSION); SVERSION = 1.01;

Затем в пользовательской программе ставится команда use Ре rson 1.01; - это позволяет проверить версию и убедиться в том, что она равна указанной или превышает ее. Помните, что версия не обязана точно совпадать с указанной, а должна быть не меньше ее. Впрочем, в настоящее время параллельная установка нескольких версий одного модуля не поддерживается.

> Смотри также-

Документация по стандартному модулю UNIVERSAL. Ключевое слово use описано в рег мпс(1).



13.9. Создание класса с поддержкой наследования

Проблема

Вы не уверены в том, правильно ли вы спроектировали свой класс и может ли он использоваться в наследовании.

Решение

Воспользуйтесь «проверкой пустого субкласса».

Комментарий

Допустим, вы реализовали класс Person с конструктором new и методами age и name. Тривиальная реализация выглядит так:

package Person; sub new {

my Sclass = shift;

my Sself = { },

return bless Sself, Sclass,

sub name {

my Sself = shift; Sself->{NAME} = shift if @ ; return $self->{NAME};

sub age {

my Sself = shift, Sself->{AGE} = shift if @ , return Sself->{AGE};

Пример использования класса может выглядеть так:

use Person,

my Sdude = Person->new(); $dude->name("Jason"); Sdude->age(23),

printf %s is age %d \n, Sdude->name, $dude->age;

Теперь рассмотрим другой класс с именем Employee;

package Employee; use Person, @ISA = (Person"); 1;

Ничего особенно интересного. Класс всего лишь загружает класс Person и заявляет, что все необходимые методы Employee наследует от Person. Поскольку Employee не имеет собственных методов, он получит от Person все методы.



0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 [ 151 ] 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242