Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > Perl: Общие вопросы > Константы |
Автор: ginnie 6.10.2008, 17:12 | ||||
Уважаемые коллеги! В очередной раз читая Ларри Уолл, Том Кристиансен, Джон Орвант. Программирование на Perl, узнал для себя кое-что новое про константы. Решил помучить вас! Вопрос: чем отличаются (не буквално, а принципиально ![]()
и
приведите подтверждение вашего ответа ![]() |
Автор: GreenFactory 6.10.2008, 17:53 | ||
sub const_test() предпочтительнее sub const_test тем, что идёт проверка что Вы используете константы именно как константы, а не как подпрограммы. А вообще, мой Вам совет использовать use constant А знание о том, что это на самом деле sub ...() {} пометить как академическое и не использовать.
Если раскомментировать const_test, то ничего не произойдёт Если раскомментировать const_test2 или const_test3 будет Too many arguments for main::const_test3 at t.pl line 22, near "50)" Execution of t.pl aborted due to compilation errors. |
Автор: ginnie 6.10.2008, 18:05 | ||
Уважаемый GreenFactory, спасибо за совет по поводу use constant, я его использую ![]()
замечание верное, но несущественное, т.к. вероятность написания const_test(50) очень мала (гораздо больше вероятность написания const_test = 50, но это уже не сработает). Кроме того вариант с &const_test(50) эту проблему обойдет ![]() |
Автор: GreenFactory 6.10.2008, 18:30 | ||||
Как раз писал следующее. Подумав над вопросом ещё, понял (вспомнил), как этот момент обходится
Из-за этого момента меня несколько раздражают прототипы. Добавлено через 13 минут и 40 секунд Это не совсем так. В прямом варианте, конечно мала, но в несколько изменённом, вполне.
|
Автор: Ramirez 6.10.2008, 18:51 |
Недавно близкая тема была: http://forum.vingrad.ru/index.php?showtopic=219798&view=findpost&p=1616168 попробую погадать на кофейной гуще: Основная идея думаю изложена в http://www.perl.com/doc/manual/html/pod/perlsub.html#Constant_Functions ...по сути все константы есть функции, насколько я понимаю. Визуально разница в том, что при попытке переопределить функцию объявленную с () будет пердупреждение, что такая уже есть, а если без скобок - то никаких предупреждений не будет. в скобках компилятор ожидает прототип увидеть, по идее. а наличие/отсутствие скобок, видимо, и отличает inline/не-inline функции. От этого зависит когда будет вычисляться функция - на этапе компиляции или на этапе выполнения. попробую предположить, что от этого как раз зависит то, что константу нельзя переопределить... PS: а предупреждение выдается похоже вот почему: если функция вычислялась на этапе компиляции, то все методы скомпилированные до переопределения этой функции и после ее переопределения будут использовать старое значение. |
Автор: ginnie 6.10.2008, 19:13 | ||||||||
Ramirez, Вы верно указали ссылку, константы в perl представляют собой inline-функции. Inline-функция обязательно должна иметь прототип (), на это я и хотел обратить внимание.
|
Автор: ginnie 6.10.2008, 19:35 | ||||
Ramirez,
если использовать use warnings, то предупреждение о переопределении будет в обоих случаях, для варианта с прототипом будет еще сообщение типа Prototype mismatch: sub main::test () vs none.
это необходимое условие, но не достаточное, надо еще, чтобы тело функции после оптимизации и константных вычислений представляло собой константу, или лексическую переменную, на которую нет других ссылок. |
Автор: KSURi 6.10.2008, 20:26 |
use Readonly::XS |
Автор: GreenFactory 7.10.2008, 19:27 |
На каждую хитрую ж.... Найдётся достойный ответ ![]() "А Readonly, что он, всего лишь делает SvREADONLY_on() если все же припекло. Что интереснее, что некоторым вещам можно делать SvREADONLY_off()" http://community.livejournal.com/ru_perl/275905.html?thread=2951873#t2951873 Из этого следует, что если уж приспичит поменять, поменяют... Следовательно, у нас нет констант. |
Автор: ginnie 7.10.2008, 22:16 |
GreenFactory, если Вы смотрели модуль Readonly.pm, то он использует макрос SvREADONLY только для скаляров и только при установленном модуле Readonly::XS, во всех остальных случаях используется связывание (tie) ![]() Если под константой понимать значение, вычисляемое и подставляемое при компиляции, то у нас есть константы ![]() |
Автор: GreenFactory 13.10.2008, 20:21 | ||
Из википедии: Конста́нта (от лат. constans - постоянный, неизменный) — некоторая величина, не изменяющая своё значение в рамках рассматриваемого процесса. Из этого утверждения следует, что если я изменил "константу", то она автоматом перестаёт ей быть. А на счёт tie и SvREADONLY SvREADONLY надёжнее, т.к. untie есть в чистом перле, а SvREADONLY_off только в XS. |
Автор: ginnie 13.10.2008, 21:14 | ||
GreenFactory, Вы не изменяете константу, Вы подменяете понятие константы на понятие вызова функции. В Perl они похожи, но это не одно и тоже ![]() Вот Ваш пример с eval(), после perl -MO=Deparse
где интерпретатору и мне очевидно, где константы ('constant text'), а где вызов функции (CONSTANT_TEXT). Соглашусь, что есть конструкции, где константы использовать технически невозможно (типа eval('code')). |
Автор: GreenFactory 13.10.2008, 22:19 | ||||
Ничего такого, моё представление о константах можно назвать классическим. Как раз в Perl это одно и тоже. Вызов функции, подпадающее под некоторые условия, заменяется на результат её выполнения при компиляции. Этой побочной фишкой функций и решили воспользоваться для констант. Этого не может быть, т.к. для него констант нет, есть только функции, подпадающее под некоторые условия. Немного подправил пример.
и
|
Автор: ginnie 13.10.2008, 22:37 | ||
GreenFactory, новый пример у меня выводит
а у Вас что? |
Автор: GreenFactory 15.10.2008, 15:06 | ||||
Простите. Писал на лету, вот исправленный код
Выводит
|
Автор: tishaishii 21.10.2008, 16:22 |
*::CONSTANT_TEXT? |
Автор: ginnie 21.10.2008, 17:03 |
tishaishii, а есть разница между *main::CONSTANT_TEXT и *::CONSTANT_TEXT? |
Автор: gcc 31.12.2008, 13:49 |
нашел одну большу программу которая мне нужна будет где используется use constant но так и не понял зачем вообще используються константы, может кто-то объяснить? чем от них выгода? или это как понимать? я примеры нашел конечно, но смысла не понял |
Автор: tolkien 1.1.2009, 19:54 |
Константа - в переводе с греческого неизменный, постоянный. Константа только для чтения. Ее используют только тогда когда ее значение на протяжении всей жизни приложения не изменяется и остается постоянным. Кроме того что это логически правильно так еще и код с ними работает быстрее чем с обычными переменными т.к язык программирования оптимизирует код. Вместо лексических имен переменных подставляет их значения на этапе компиляции. |