2010-04-12 1 views
2

Мне показалось немного странным, что я должен анонимно обернуть определенные подпрограммы при указании аргумента -command для виджетов Tkx.Должен ли я всегда предоставлять аргумент командной строки Tkx анонимной подпрограмме?

Отрывок из TkDocs tutorial демонстрирует это:

my $cb = $frm->new_ttk__button (-text => "Calculate", 
           -command => sub {calculate();} ); 

sub calculate { 
    $meters = int(0.3048*$feet*10000.0+.5)/10000.0 || ''; 
} 

Почему это не работает, когда я пишу -command => &calculate() или -command => \&calculate()?

ответ

6

Вы не синтаксис совершенно прав. В ваших примерах вызывается подпрограмма (& обходит любые прототипы) и передает либо возвращаемое значение (&calculate()), либо ссылку на него (\&calculate()) на опцию -command. Вы хотите присвоить ссылку на саму подпрограмму, которую вы можете сделать с помощью:

-command => \&calculate 

Обратите внимание на отсутствие задних скобках. Также обратите внимание, что вы не можете передавать аргументы таким образом. Если вы хотите сделать, что вам нужно либо обернуть вызов в анонимной подпрограммы:

-command => sub { calculate(12) } 

или передать опцию ссылку ARRAY вместо ссылки CODE:

-command => [\&calculate, 12] 

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

-command => sub { calculate($x) } # creates a closure over $x 
-command => [\&calculate, $x]  # makes a copy of $x 

Используя первые изменения формы в $x будут видны при вызове команды. Во второй форме их не будет; каждый вызов будет видеть значение в момент создания привязки. Обе формы полезны; вам просто нужно проявлять здравый смысл при принятии решения о том, что использовать.

+0

Я просвещен. Но я до сих пор не понимаю, почему синтаксис '\ & calculate' не работает со мной ... – Zaid

+0

@ Zaid: Я запустил код примера, изменяя' sub {calculate()} 'на' \ & calculate', и он работал как ожидается. Говорить, что это «не работает», безнадежно расплывчато. Что случилось, когда вы попробовали? –

+0

'\ & calculate' сам по себе работает. Массивref был тем, что меня сбивало с толку, но ваше объяснение объясняет почему. Спасибо, куча ... Если бы я мог, я бы повысил вдвое больше! – Zaid

2

Он должен работать с -command => \&calculate. Обратите внимание на отсутствие круглых скобок.

Приведенные примеры фактически выполняют подпрограмму и присваивают возвращаемое им значение ключу -command.

Для получения дополнительной информации см perlsub и perlref

+0

Нет. Он не выполняется с парами или без них. – Zaid

+0

Было бы смешно видеть ' \% рассчитывать' работу без круглых скобок. Что делать, если мне нужно передать аргументы? – Zaid

+0

Это должно быть '\ & calculate', а не' \% calculate' ... – Zaid

2

Зайд сказал: «Я просветленным Но я до сих пор не понимаю, почему \ & высчитывает синтаксис не работает со мной ... -. Заид 24 минут назад»

Zaid, \ & расчет синтаксиса действительно работает. Вы пытались использовать синтаксис calculate() \ &. Первая привязка к «ссылке на подпрограмму, которая будет запущена позже», последняя связывается как «ссылка на (возвращаемое значение вызова вычисляется без аргументов и обходит прототипы аргументов).

У вас есть более длинный, компилируемый фрагмент кода, который мы можем использовать для тестирования/анализа? Я недавно не знаком с TK.

+0

Код на веб-сайте TkDocs. Следуйте по ссылке в исходном сообщении и измените анонимную подпрограмму на '\ & calculate' и сообщите мне, если она сработает для вас. Это не для меня. – Zaid