Объекты вместо глобальных переменных в Perl - PullRequest
2 голосов
/ 17 января 2011

Я не знаю, правильно ли это делать. Но я ищу учебники / статьи по использованию объектов вместо глобальных переменных для хранения состояния. Например,

package something
# some code here... 
# that generates errors and uses
# something::errors to track errors. 


package something::errors
sub new {
    my ($this) = @_;
    bless $this;
    return $this; 
}
sub setErrors{ 
    my ($this, @errors) = @_;
    $this->{errors} = \@errors;
}
sub getErrors{
    my ($this) = @_;
    return $this->{errors};         
} 

Это лучше, чем использование глобальных переменных? Есть ли недостатки этого? Любой подход, который может быть лучше?

Спасибо.

Ответы [ 4 ]

2 голосов
/ 17 января 2011

Вам нужен учебник? Знаете ли вы, что в Perl куча уроков, чем вы можете потрясти палкой?

Введите в этой команде:

$ perldoc perl
[... a bunch of stuff]
Tutorials

    perlboot            Perl OO tutorial for beginners
    perltoot            Perl OO tutorial, part 1
    perltooc            Perl OO tutorial, part 2
    perlbot             Perl OO tricks and examples

Острота

Все, что вам нужно сделать, это просто запустить:

$ perldoc perlboot

чтобы увидеть конкретное руководство. Если у вас есть это через веб-страницу оформления заказа Документация Perl .

И они говорят, что Perl сложен. В конце концов, Unix поставляется со встроенной документацией, и насколько это сложно?

Кстати, объекты Perl не так сложны в использовании или понимании. И они действительно помогают очистить ваш код. Если вы используете хэши хэшей, массивы или массивы хэшей или массивы хэшей, вам действительно следует использовать объектно-ориентированный Perl.


Подсказка!

Взгляните на последнюю документацию Perl по переменным состояния . Это сделано для того, чтобы делать именно то, что вы хотите.

2 голосов
/ 17 января 2011

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

IMO, объекты наиболее полезны, потому что они обеспечивают способ инкапсуляциикусок данных и связать его с набором поведений.

В коде наблюдаются несколько подсказок, указывающих на то, что ООП может быть хорошим путем:

  1. Многие подпрограммы, которые принимаютта же группа аргументов.
  2. Вы работаете с неоднородными структурами данных глубиной 3 или более уровней.

Итак, все (или большинство) ваших подпрограмм имеют 3 или 4общие аргументы?

sub whiz {
    my ($foo, $bar, $baz, $pogo) = @_;
    # blah
}

sub bang {
    my ($foo, $bar, $baz, $whibble) = @_;
    # blah
}

sub fiz {
    my ($foo, $bar, $baz, $smot) = @_;
    # blah
}

Если вы обнаружите, что ваш код выглядит так, то, возможно, $foo, $bar и $baz должны быть частью объекта, который группирует все эти беспорядочные вещи в одном месте.

Возможно, у вас есть большой объект данных или состояния, который выглядит примерно так:

{   Foo => [ { a => 1, z => 3 }, [qw( milk milk lemonade)], ],
    quack => { round => 'the', corner => [qw( fudge is made )] },
...
}

Подумайте о том, чтобы разбить эту структуру на меньшие связанные, носимые единицы.Это ваши объекты.

Посмотрите на эту структуру:

{   teacher => $miss_jones,
    students => [ $bobby, $suzy, $joseph, $jenny ],
    principal => $mr_goodcop,
    vice_principal => $mr_badcop,
    custodian => $mr_mopitup,
}

И представьте, что каждая переменная была расширена в свою собственную с собственным набором полей.Некоторые присутствуют во всех переменных, другие уникальны для некоторого подмножества записей.Но если $ miss_jones находится в классе $ teacher, мы можем позвонить $miss_jones->add_student( $bobby ), не беспокоясь о том, как Учитель хранит учащихся.

Это принципы, которые я использую, чтобы определить, когда использовать ООП.

1 голос
/ 17 января 2011

Какой подход может быть лучше?

См. Главу 13 Perl Best Practices почему и как использовать надлежащие исключения.Эта тема также неоднократно упоминалась в Переполнении стека: Поиск Google , Поиск SO , Теги SO

1 голос
/ 17 января 2011

Что ж, вашему пакету все еще требуется (предположительно глобальная) переменная какого-то рода, чтобы благословлять и использовать в качестве аргумента # 1 в будущих вызовах методов, поэтому я не вижу, как это улучшит ситуацию в этом отношении. IOW вам нужна глобальная переменная независимо от того, храните ли вы ошибки в простом глобальном массиве или используете объект something::errors для их хранения.

Хотя использование объекта не влияет на необходимость сохранения глобального состояния, это означает, что вы можете контролировать, какие операции можно выполнять более точно, и это хорошо для обслуживания. (Техническое обслуживание - это всего лишь , ограничивающий возможный набор поведений любого данного фрагмента кода до приемлемого размера .)

Я думаю, что важный вопрос: «Будет ли этот список ошибок когда-либо достаточно отличаться от простого массива, чтобы оправдать использование для него специального типа?» Если у вас есть только операции setErrors() и getErrors(), и вы не предполагаете когда-либо выполнять какую-либо фильтрацию / обработку во время вызова setErrors(), тогда я бы сказал «нет», поскольку эти операции достаточно мощны, чтобы позволить вы делаете все, что можете, с простым массивом, чтобы они не обеспечивали никакой «безопасности». Если, с другой стороны, вы хотите избежать вероятности того, что ошибки будут случайно удалены из списка, вы можете использовать метод addErrors() вместо метода setErrors(), и теперь вы можете более убедительно утверждать, что было какое-то преимущество в использовании отдельный тип.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...