Общие сведения о пространствах имен в POE-Tk

Я опубликовал "Как понять использование POE-Tk для уничтожения?" в попытке уменьшить ошибку в моем производственном коде до тестовый случай. Но, похоже, решение тестового примера работает не по полной программе.

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

Вот раздел Session::Create моего приложения POE-Tk.


POE::Session->create(
    inline_states => {
        _start      => \&ui_start,
        get_zone    => \&get_zone,
        ping        => \&ping,
        mk_disable  => \&mk_disable,
        mk_active   => \&mk_active,
        pop_up_add => \&pop_up_add,
        add_button_press => sub {
            my ($kernel, $session, $heap) = @_[KERNEL, SESSION, HEAP];
            print "\nadd button pressed\n\n";
            &validate;
        },
        ih_button_1_press => sub {
            my ($kernel, $session, $heap) = @_[KERNEL, SESSION, HEAP];
            print "\nih_button_1 pressed\n\n";
            if( Tk::Exists($heap->{ih_mw}) ) {
                print "\n\nih_mw exists in ih_button_1_press\n\n";
            } else {
                print "\n\nih_mw does not exist in ih_button_1_press\n\n";
            }
            1;
            $heap->{ih_mw}->destroy if Tk::Exists($heap->{ih_mw});
            &auth;
        },
        pop_up_del => \&pop_up_del,
        auth        => \&auth,
#       validate    => \&validate,
        auth_routine => \&auth_routine,
        raise_widget    => \&raise_widget,
        del_action  => \&del_action,
        over        => sub { exit; }
    }
);

add_button_press вызывается здесь;


sub pop_up_add {
    ...
    my $add_but_2 = $add_frm_2->Button( 
        -text => "Add Record",
        -command => $session->postback("add_button_press"),
        -font => "{Arial} 12 {bold}") -> pack(
            -anchor => 'c',
            -pady => 6,
        );
    ...
}

validate создает виджет верхнего уровня $heap->{ih_mw};


sub validate {
    ...
    if( ! $valid ) {
        print "\n! valid entered\n\n";
        $heap->{label_text} .= "Add record anyway?";
        my $lt_ref = \$heap->{label_text};
    ...
        my $heap->{ih_mw} = $heap->{add_mw}->Toplevel( -title => "ih_mw");
    ... 
        if( Tk::Exists($heap->{ih_mw}) ) {
            print "\n\nih_mw exists in validate\n\n";
        } else {
            print "\n\nih_mw does not exist in validate\n\n";
        }
    ...
        my $ih_but1 = $heap->{ih_mw}->Button( -text => "Add",
            -font => 'vfont',
            -command => $session->postback("ih_button_1_press"),
            )->pack( -pady => 5 );
    ...
}

Нажатие $ih_but1 приводит к этому;

C:\scripts\alias\resource>alias_poe_V-3_0_par.pl

кнопка добавления нажата

вспомогательная проверка называется

! действительный введенный

ih_mw существует в проверке

ih_button_1 нажата

ih_mw не существует в ih_button_1_press

Таким образом, виджет $heap->{ih_mw} кажется неизвестным анонимной подпрограмме ih_button_1_press даже при включении "($kernel, $session, $heap) = @_[KERNEL, SESSION, HEAP];"


person jpolache    schedule 20.07.2009    source источник
comment
Пожалуйста, попробуйте проверить, действительно ли определены $heap и $heap-›{ih_mw)(). Если $heap не определен, у вас может возникнуть та же проблема, что и в предыдущем посте.   -  person Inshallah    schedule 21.07.2009
comment
Я добавил if(defined($heap)) перед if(Tk::Exists($heap-›{ih_mw})). Он вернулся, что $heap определен. ih_button_1 нажата... определена куча... ih_mw не существует в ih_button_1_press...   -  person jpolache    schedule 21.07.2009
comment
А как насчет определенных($heap-›{ih_mw})?   -  person Inshallah    schedule 21.07.2009


Ответы (1)


Откуда взялась $heap в &validate? Вы не передаете его как параметр. Может ли $heap в &validate и $heap в &in_button_1_press не быть одним и тем же? Пробовали ли вы напечатать строковую форму $heap, чтобы увидеть, совпадают ли адреса в двух функциях?

person Andrew Barnett    schedule 20.07.2009
comment
Некоторый отсутствующий код; использовать Тк; использовать POE qw( Loop::TkActiveState ); Из perldoc POE::Session; Соглашение о вызовах POE::Session sub handle_event { my ($kernel, $heap, $parameter) = @_[KERNEL, HEAP, ARG0]; ...; } Или использование встроенных C$_[KERNEL], C$_[HEAP] и C$_[ARG0], как это делается в большинстве примеров. То, что здесь происходит, довольно просто. Perl передает параметры подпрограммам или методам с помощью массива @_. KERNEL, HEAP, ARG0 и другие — это константы, экспортируемые POE::Session (который включается бесплатно, когда программа использует POE). волокнистая форма $heap? - person jpolache; 20.07.2009
comment
Вы не ответили на мой вопрос: откуда $heap в &validate? Вы вызываете &validate из add_button_press без каких-либо аргументов, поэтому, если вы получаете $heap в &validate через $heap = @_[HEAP], вас ждет сюрприз. Кроме того, форма вызова функции &validate, в отличие от простой проверки, не наследует @_ из контекста вызова. - person Andrew Barnett; 21.07.2009
comment
Упс. Это выглядит неправильно (при проверке): my $heap-›{ih_mw} ... Попробуйте без 'my' и посмотрите, будет ли это работать лучше. - person Andrew Barnett; 21.07.2009
comment
Эндрю, если вы опубликуете это как ответ, я буду рад проверить и проголосовать за него;). Большое спасибо. - Джон - person jpolache; 21.07.2009
comment
Из perlsub (1): # Делает текущую @_ видимой для вызываемой подпрограммы. - person Inshallah; 21.07.2009
comment
Дох! Я знал, что это было что-то вроде этого. Спасибо Иншалла. - person Andrew Barnett; 21.07.2009