Модераторы: korob2001, ginnie

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> ООП в perl 
:(
    Опции темы
DEER
Дата 16.11.2005, 12:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 749
Регистрация: 12.4.2005
Где: г. Рязань

Репутация: 1
Всего: 13



Народ, я слышал что в perl можно создавать классы,
хотелось бы узнать как?
если можно маленький пример, класса
скажем с двумя полями, и одним методом, который складывает эти поля и возвращает сумму

smile
Заранее спасибо


--------------------
 
PM MAIL WWW ICQ MSN   Вверх
arto
Дата 16.11.2005, 13:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1495
Регистрация: 31.10.2004

Репутация: 38
Всего: 40



perldoc perltoot
PM MAIL ICQ   Вверх
korob2001
Дата 16.11.2005, 13:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2871
Регистрация: 29.12.2002

Репутация: 31
Всего: 61



Вобщем написал тебе такой вот тестовый класс. Сохрание его под именем Sum.pm
Код

package Sum;

# Конструктор класса
sub new {
    my $check = shift;
    my $class = ref( $check ) || $check;
    my $self  = [@_];
    return bless( $self, $class );
}

# Метод принимает любое кол-во цифр и сохраняет их
sub addNumbers {
    my $self = shift;
    # Проверяем параметры, что они действительно являются числами
    for ( @_ ) {
          if ( /^\d+(?:\.\d+)?$/ ) {
               # Если число сохраним его как член класса
               push( @$self, $_ );
          }
    }
}

# Метод возвращает сумму всех чисел
sub getSum {
    my $self = shift;
    my $sum = 0;
    foreach (@$self) {
          $sum += $_;
    }
  return $sum;
}

# Метод возвращает общее кол-во чисел
sub getColNumbers {
    my $self = shift;
    return scalar @$self;
}

# Метод возвращает все числа в виде строки разделённой запятыми
sub toString {
    my $self = shift;
    my $str = "";
    $str .= "$_, " for ( @$self );
    $str =~ s/\D+$//;
    return $str;
}

# Метод возвращает среднее значение всех чисел
sub getAverage {
    my $self = shift;
    my $sum = 0;
    map { $sum += $_ } @$self;
    $sum /= @$self;
    return $sum;
}

# Мтод очищает члены класса
sub clearMemory {
    my $self = shift;
    @$self = ();
}

# Классы всегда должны возвращать истену, как и модули.
1;

Тепрь в тот же каталог, сохрани следующую программу, под любым именем лишь бы расширение было как у выполняемого файла, как правило это .pl или .cgi. Я назвал его test.pl
Код

#!/usr/bin/perl -w
use strict;

# Укажим Perl, что модули нужно искать и в текущем каталоге
use lib qw(.);
# Подключаем класс
use Sum;

# Создаём объект и сразу добавляем 3 числа
my $sum = Sum->new(10,20,30);

# выводим сумму чисел
print "Sum of numbers (" . $sum->toString() . ") is: " . $sum->getSum() . "\n";

# Добавим ещё пару чисел
$sum->addNumbers(40,10);

# Выводим общее кол-во имеющихся чисел
print "Total numbers: " . $sum->getColNumbers() . "\n";

# Выводим ещё раз сумму чисел
print "Sum of numbers (" . $sum->toString() . ") is: " . $sum->getSum() . "\n";

# Выводим среднее значение
print "Average of numbers (" . $sum->toString() .  ") is: " . $sum->getAverage() . "\n";

# Удалим все цифры
$sum->clearMemory();

# Проверим, что мы действительно всё очистили
print "Total numbers is: " . $sum->getColNumbers();

Ну и читай коментарии, там всё пояснено. Если чего-то не поймёшь, спрашивай.


--------------------
"Время проходит", - привыкли говорить вы по неверному пониманию. 
"Время стоит - проходите вы".
PM MAIL WWW ICQ MSN   Вверх
DEER
Дата 16.11.2005, 13:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 749
Регистрация: 12.4.2005
Где: г. Рязань

Репутация: 1
Всего: 13



Спасибо!
Я так понял, что внутри каждого метода мы получаем доступ к классу(его методам и всойствам) через shift. Так?
Тогда можно сделать так? то есть внутри класса вызывать его методы?
Код

# Метод возвращает сумму всех чисел    
sub getSum {    
    my $self = shift;    
    my $sum = 0;    
    foreach (@$self) {    
          $sum += $_;    
    }    
  return $sum;    
}
# Метод возвращает среднее значение всех чисел    
sub some_func {    
    my $self = shift;    
    self->getSum();
}

также можно объявить именованное свойство в конструкторе
Код

$self->{NAME}   = undef;

и тогда для этого свойства нужно описать функцию
Код

        sub name {
            my $self = shift;
            if (@_) { $self->{NAME} = shift }
            return $self->{NAME};
        }

Так?


--------------------
 
PM MAIL WWW ICQ MSN   Вверх
korob2001
Дата 16.11.2005, 14:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2871
Регистрация: 29.12.2002

Репутация: 31
Всего: 61



Ты почти всё верно понял, но shift всеголишь вытаскивает первый елемент массива и возвращает его.
Код

my @color = qw( red green blue );
my $color = shift @color;

Теперь переменная $color содержит строку "red", а массив @color содержит теперь 2 елемента "green" и "blue". Вобщем игра со стёком.

В нашем случае, мы не указываем имени массива из которого нужно извлекать первый елемент, если массив не указан и shift находится внутри подпрограммы, то будет извлечён первый елемент массива @_, если shift вне подпрограммы и не указан явно массив, то будет извлечён первый елемент массива @ARGV.

Т.е. когда ты вызываешь метод, первым параметром всегда является объект. Это легко проверить. Добавь такой метод в класс Sum.pm
Код

# Метод возвращает пакет в котором он находится
sub getInfo  {
       return shift;
}

Ну и конечно же вызови его из основной программы. Увидишь примерно такую строку:
Sum=ARRAY(0x2252f8)
где Sum имя пакета, а ARRAY(0x2252f8) ссылка на анонимный массив, в нашем случае в нём сохраняются члены класса. Мы его создаём в конструкторе.

Внутри класса можно обращаться к методам и напрямую, указав его имя, но всё же рекомендуется обращаться через обьект, потому мы сначала извлекаем объект с помощью shift, ну а затем через него обращаемся к методам. Кстати можно создавать закрытые методы, для этого нужно, что бы имя метода начиналось с символа _ :
Код

# Этот метод нельзя вызвать из вне, только внутри класса, это примерно то же, если бы
# мы в Java создали метод с доступом private
sub _closedMethod {
       return "Hello";
}

Можно так же реализовать закрытость ещё более надёжную, если заключить члены в блок (т.е. в фигурные скобки ) и объявить их как локальные, через my.

Это сообщение отредактировал(а) korob2001 - 16.11.2005, 14:12


--------------------
"Время проходит", - привыкли говорить вы по неверному пониманию. 
"Время стоит - проходите вы".
PM MAIL WWW ICQ MSN   Вверх
DEER
Дата 16.11.2005, 14:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 749
Регистрация: 12.4.2005
Где: г. Рязань

Репутация: 1
Всего: 13



Угу почти понятно smile
Спасибо!


--------------------
 
PM MAIL WWW ICQ MSN   Вверх
korob2001
Дата 16.11.2005, 14:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2871
Регистрация: 29.12.2002

Репутация: 31
Всего: 61



Ну вообще-то ООП, тема довольно не маленькая, но очень затягивающая. Очень хорошо она описана в книге "Программирование на Perl" Ларри Уолл, Том Кристеасон, Джон Орвант. Она помоему есть в нашей библиотеке, посмотри. Ну а так же поищи через поисковик, здесь уже много раз поднимались подобные темы.


--------------------
"Время проходит", - привыкли говорить вы по неверному пониманию. 
"Время стоит - проходите вы".
PM MAIL WWW ICQ MSN   Вверх
korob2001
Дата 16.11.2005, 15:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2871
Регистрация: 29.12.2002

Репутация: 31
Всего: 61



Гость_Nick - главное спокойствие.

Отрываем "Perl - специальный справочник" Стивен Холзнер (страница 357) и читаем.

Создание приватных методов и данных

Хотя многие объектно-ориентированные языки программирования поддерживают приватные методы и переменные ( то есть внутренние методы и переменные, не достижимые вне класса или объекта ), Perl не позволяет делать этого явно.

Вы всегда можете использовать переменные с лексической областью видимости (ключевое слово my), что бы ограничить область видимости переменных текущим пакетом.

Что бы создать приватные переменные, надо воспользоваться следующим соглашением Perl: приватные имена начинаются с символа подчёркивания. В отличии от языков типа C++, Java или Delphi, это не значит, что вы не може получить доступ к приватным переменным и методам объекта. Идея состоит в том, что если имя начинается с символа подчёркивания, его не следует использовать, поскольку оно считается приватным. В следующем примере публичный ( открытый ) метод sum исплользует приватный ( закрытый ) метод _add для сложения двух велечин:
Код

package Class1;
sub new {
       my $type = {};
       $type->{OPERAND1} = 2;
       $type->{OPERAND2} = 2;
       bless( $self );
       return $self;
}

sub sum {
       my $self = shift;
       my $tem = _add( $self->{OPERAND1}, $self->{OPERAND2});
       return $temp;
}

sub _add { return shift() + shift(); }

return 1;

Вот результат использования метода sum:
Код

use Class1;
my $object1 = Class1->new();
print "Here is the sum: ", $object1->sum;

Собственно это я и имел ввиду.

Ну а так, можно создать истенно закрытый метод:
Код

my $closed = sub {
      # Тело метода
};


Или даже так, ещё больше закрытый:
Код

{
    my $closed = sub {
          # Тело метода
    };
     
    # Метод который будет использовать закрытый метод
    sub useClosed {
           my $self = shift;
           $self->$closed();
    }
}

Я так и не понял твоего сорказма, будь добр поясни.

Это сообщение отредактировал(а) korob2001 - 16.11.2005, 16:36


--------------------
"Время проходит", - привыкли говорить вы по неверному пониманию. 
"Время стоит - проходите вы".
PM MAIL WWW ICQ MSN   Вверх
Гость_Nick
Дата 16.11.2005, 16:17 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











А почему я своего сообщения не вижу?
И язык у меня не козлиный...
Я только после того как отправил сообщение увидел, что ты модератор smile
Вообще в конце того сообщения хотел извиниться, но передумал,
т.к. ну не перевариваю я когда люди толком не знают неких вещей а сообщают об этом как большие знатоки, ну сори... smile И вообще я сегодня злой какой-то... smile

А что касается закрытых методов, ты пишешь
Цитата
Кстати можно создавать закрытые методы, для этого нужно, что бы имя метода начиналось с символа _ :


Прочитай внимательнее ту цитату, которую приводишь в качестве контр аргумента:
Цитата

Хотя многие объектно-ориентированные языки программирования поддерживают приватные методы и переменные ( то есть внутренние методы и переменные, не достижимые вне класса или объекта ), Perl не позволяет делать этого явно.


Но по твоему выходит, что позволяет: ибо использование "_" для закрытия метода есть не что иное, как явное указание Perl'у на то что метод закрыт.

Цитата

Что бы создать приватные переменные, надо воспользоваться следующим соглашением Perl: приватные имена начинаются с символа подчёркивания.


Это просто соглашение и не более. Т.е. на самом деле метод не является закрытым.

Хочешь сделать закрытый метод, можно, например, так:
Код

package Foo;
my $private = sub { print "Hi,\t"; };
sub new
{
  my $prop = shift;
  return bless {}, ref $prop || $prop;
}

sub Public
{
  $private->();
  print " All!\n";
}
1;


Использование:
Код


use strict;
use foo;

my $f = new Foo();

$f->Public; # OK. Напечатает: Hi,             All!
$f->$Foo::private->(); # Can't locate object method "" via package "Foo"
$Foo::private->(); # Can't use string ("") as a subroutine ref while "strict refs" in use


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



  Вверх
korob2001
Дата 16.11.2005, 16:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2871
Регистрация: 29.12.2002

Репутация: 31
Всего: 61



Гость_Nick - ты меня тоже извини, я тоже какой-то злой сегодня. Может погода влияет?
Вобщем каждый из нас обратил внимание на то, что ему хотелось. Я собственно назвал этот метод приватным потому что раздел в книге называется:
Создание приватных методов и данных, с другой стороны я так же сказал:
Цитата

Можно так же реализовать закрытость ещё более надёжную, если заключить члены в блок (т.е. в фигурные скобки ) и объявить их как локальные, через my.

Пример этого способа привёл постом выше.

Зы: ты случайно NICK не с perl.ru, я имею ввиду 2001 год?

Это сообщение отредактировал(а) korob2001 - 16.11.2005, 16:35


--------------------
"Время проходит", - привыкли говорить вы по неверному пониманию. 
"Время стоит - проходите вы".
PM MAIL WWW ICQ MSN   Вверх
Гость_Nick
Дата 16.11.2005, 16:48 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Ну разобрались и ладно. smile

ЗЫ: Я не с perl.ru и вообще ниоткуда smile
ЗЗЫ: Я вообще очень редко бываю на каких-либо форумах, сегодня случайно забрел и не удержался от ответа. ;)

  Вверх
Kiber_rat
Дата 18.11.2005, 14:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


MACMANIAC
**


Профиль
Группа: Участник
Сообщений: 276
Регистрация: 18.4.2002
Где: Ashdod, Israel

Репутация: 7
Всего: 9



Может кому пригодится... Я тут читаю книжку "Perl best practices" by Damian Conway (есть у меня в виде html) там есть много полезного, в частности и по поводу ООП в perl. Так что рекомендую. Язык - родной англицкий smile


--------------------
Best regards!                                                             
@..@_____Ku6ep
=*=______\______KPbIC
Код
print join "",map{chr}(split/(\w{2})/,hex(int(2175.57302796298**2)))
PM WWW ICQ Skype Jabber YIM   Вверх
DEER
Дата 30.11.2005, 11:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 749
Регистрация: 12.4.2005
Где: г. Рязань

Репутация: 1
Всего: 13



Господа, а нет тонкостей(или разностей) написания классов под windows\linux?

просто написал класс, отлаживал под винды, а сейчас пытаюсь запустить всё это дело под linux'ом, он говорит
Цитата
Can't locate object method "new" via package "Analisyst" at /var/www/vhosts/...../deer.cgi


соответственно deer.cgi и Analisyst.pm лежат в одной директории

smile


--------------------
 
PM MAIL WWW ICQ MSN   Вверх
Kiber_rat
Дата 30.11.2005, 17:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


MACMANIAC
**


Профиль
Группа: Участник
Сообщений: 276
Регистрация: 18.4.2002
Где: Ashdod, Israel

Репутация: 7
Всего: 9



В *nix имеет значение регистр символов, т.е. Analisyst и analisyst - разные файлы, прежде всего проверь это smile


--------------------
Best regards!                                                             
@..@_____Ku6ep
=*=______\______KPbIC
Код
print join "",map{chr}(split/(\w{2})/,hex(int(2175.57302796298**2)))
PM WWW ICQ Skype Jabber YIM   Вверх
sharq
Дата 30.11.2005, 17:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Perl Liker
**


Профиль
Группа: Участник
Сообщений: 841
Регистрация: 13.12.2004
Где: Ростов-на-Дону

Репутация: 23
Всего: 28



DEER а ты в deer.cgi указал
Код

use lib '.';
use Analisyst;


Проверь это!

smile


--------------------
[color=gray]There's More Than One Way To Do It[/color]
PM MAIL WWW ICQ Skype   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Perl"
korob2001
sharq
  • В этом разделе обсуждаются общие вопросы по языку Perl
  • Если ваш вопрос относится к системному программированию, задавайте его здесь
  • Если ваш вопрос относится к CGI программированию, задавайте его здесь
  • Интерпретатор Perl можно скачать здесь ActiveState, O'REILLY, The source for Perl
  • Справочное руководство "Установка perl-модулей", можно скачать здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, korob2001, sharq.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Perl: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1234 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.