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

Поиск:

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


Новичок



Профиль
Группа: Участник
Сообщений: 28
Регистрация: 14.10.2006

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



Не знаю как поточнее назвать тему.

В общем такая проблема:
Есть класс один из методов которого отображается GUI. Для обработки событий GUI используются ссылка на подпрограмму.
Например
Код

package test;

sub new {
    my $self = {};
    return bless $self;
}

sub show {
    my $self = shift;
    my $win = Gtk2::Window->new;
    $win->signal_connect(delete_event => \&quit);
}

sub quit {

}


Как в подпрограмме quit получить доступ к объекту? Т.е. $self.
Функции обратного вызова планируется хранить в отдельном модуле и экспортировать в класс.
PM MAIL WWW   Вверх
ZibSoft
Дата 7.9.2009, 07:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 28
Регистрация: 14.10.2006

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



Гоню.... не стоит писать посты когда спать охото smile))

Ведь при вызове quit видим же и $self и $win. Так?
PM MAIL WWW   Вверх
sir_nuf_nuf
Дата 7.9.2009, 11:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 920
Регистрация: 6.1.2008

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



нет, не так. Из close вы никогда (почти) не увидите лексические переменные другого блока (процедуры)
что бы при вызове quit было видно  $self и $win
нужно либо создать замыкание (closure)

Код

sub show {
    my $self = shift;
    my $win = Gtk2::Window->new;
    $win->signal_connect(delete_event =>sub { "и здесть код quit, использующий $win и $self")});
}


либо сделать переменные локальными
Код

sub show {
    local $self = shift;
    local $win = Gtk2::Window->new;
    $win->signal_connect(delete_event => \&quit);
}
sub quit {
}


Это сообщение отредактировал(а) sir_nuf_nuf - 7.9.2009, 11:21


--------------------
user posted image
user posted image
PM MAIL Jabber   Вверх
ZibSoft
Дата 7.9.2009, 15:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 28
Регистрация: 14.10.2006

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



Если просто указать local $self, то интепретатор возмущается
Код

Global symbol "$self" requires explicit package name at.........

Включена прагма strict.
Если указать our $self, то в пакете где хранятся подпрограммы обратного вызова $self не видно :-(, там strict отключена иначе возмущается.

А можно поподробнее про
Цитата

Из close вы никогда (почти) не увидите лексические переменные другого блока (процедуры)

про почти, что вы имели ввиду?

P.S. Можно конечно не мучиться и использовать первый вариант, который
Код

sub show {
    my $self = shift;
    my $win = Gtk2::Window->new;
    $win->signal_connect(delete_event =>sub { "и здесть код quit, использующий $win и $self")});
}

но код будет не красивый и работать с ним проблематично. Рисую меню и на каждый пункт меню свой обработчик, а меню большое...
Может есть какие-то другие варианты решения?
PM MAIL WWW   Вверх
sir_nuf_nuf
Дата 7.9.2009, 16:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 920
Регистрация: 6.1.2008

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



под "почти"  - имелся в виду XS извращения типа PadWalker. но это хак.

Объясните, зачем вам видеть переменные лексические переменные другой процедуры ?
это  вообще кошмарный прием - и ни разу не "красиво"

Сделайте так - заведите у колбэков параметры и передавайте переменные через них
(ну опять таки через замыкание)
Код

sub show {
    my $self = shift;
    my $win = Gtk2::Window->new;
    $win->signal_connect(delete_event =>sub {close($self, $win))});
}
sub close {
    my ($caller_obj, $win) = @_;
    #....
}

Это, имхо, наиболее корректно.


--------------------
user posted image
user posted image
PM MAIL Jabber   Вверх
ZibSoft
Дата 10.9.2009, 12:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 28
Регистрация: 14.10.2006

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



Сделаю, делаю как вы порекомендовали, через ссылки на анонимные подпрограммы.
Так проще.
Спасибо smile
PM MAIL WWW   Вверх
sir_nuf_nuf
Дата 10.9.2009, 13:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 920
Регистрация: 6.1.2008

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



Лучше посмотрите на последний вариант.
Он тоже через ссылки на анонимные процедуры (они называются замыканиями),
но так код обработчиков будет у вас выделен в отдельные процедуры и может быть
использован повторно.


--------------------
user posted image
user posted image
PM MAIL Jabber   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Perl"
korob2001
sharq
  • В этом разделе обсуждаются общие вопросы по языку Perl
  • Если ваш вопрос относится к системному программированию, задавайте его здесь
  • Если ваш вопрос относится к CGI программированию, задавайте его здесь
  • Интерпретатор Perl можно скачать здесь ActiveState, O'REILLY, The source for Perl
  • Справочное руководство "Установка perl-модулей", можно скачать здесь


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

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


 




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


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

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