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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Константы, важность прототипа 
V
    Опции темы
ginnie
Дата 6.10.2008, 17:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Комодератор
Сообщений: 1287
Регистрация: 6.1.2008
Где: Москва

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



Уважаемые коллеги!

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

Вопрос: чем отличаются (не буквално, а принципиально  smile ) функции

Код

sub const_test {
    12;
}


и

Код

sub const_test () {
    12;
}


приведите подтверждение вашего ответа  smile 

Это сообщение отредактировал(а) ginnie - 6.10.2008, 17:12


--------------------
Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям. (Мартин Фаулер. Рефакторинг)
PM MAIL Skype Jabber   Вверх
GreenFactory
Дата 6.10.2008, 17:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



sub const_test() предпочтительнее sub const_test тем, что идёт проверка что Вы используете константы именно как константы, а не как подпрограммы.
А вообще, мой Вам совет использовать use constant
А знание о том, что это на самом деле sub ...() {} пометить как академическое и не использовать.

Код

use strict;
use warnings;

sub const_test {
    12;
}

sub const_test2() {
    12;
}

use constant const_test3 => 12;

print const_test, "\n";
print const_test2, "\n";
print const_test3, "\n";
print "===========\n";


#print const_test(50), "\n";
#print const_test2(50), "\n";
#print const_test3(50), "\n";



Если раскомментировать 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.


Это сообщение отредактировал(а) GreenFactory - 6.10.2008, 17:58
PM MAIL   Вверх
ginnie
Дата 6.10.2008, 18:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Комодератор
Сообщений: 1287
Регистрация: 6.1.2008
Где: Москва

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



Уважаемый GreenFactory,

спасибо за совет по поводу  use constant, я его использую smile

Цитата

тем, что идёт проверка что Вы используете константы именно как константы


замечание верное, но несущественное, т.к. вероятность написания const_test(50) очень мала (гораздо больше вероятность написания const_test = 50, но это уже не сработает). Кроме того вариант с &const_test(50) эту проблему обойдет  smile


--------------------
Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям. (Мартин Фаулер. Рефакторинг)
PM MAIL Skype Jabber   Вверх
GreenFactory
Дата 6.10.2008, 18:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Как раз писал следующее.

Подумав над вопросом ещё, понял (вспомнил), как этот момент обходится
Код

print &const_test2(50), "\n";
print &const_test3(50), "\n";

Из-за этого момента меня несколько раздражают прототипы.

Добавлено через 13 минут и 40 секунд
Цитата(ginnie @  6.10.2008,  18:05 Найти цитируемый пост)
вероятность написания const_test(50) очень мала

Это не совсем так.
В прямом варианте, конечно мала, но в несколько изменённом, вполне.

Код

use strict;
use warnings;

sub const_test {
    "Предисловие... ";
}

print const_test "А куда же делся текст?";

PM MAIL   Вверх
Ramirez
Дата 6.10.2008, 18:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 305
Регистрация: 18.1.2005
Где: Moscow, ExUSSR

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



Недавно близкая тема была:
http://forum.vingrad.ru/index.php?showtopi...t&p=1616168

попробую погадать на кофейной гуще:

Основная идея думаю изложена в
http://www.perl.com/doc/manual/html/pod/pe...stant_Functions

...по сути все константы есть функции, насколько я понимаю. 

Визуально разница в том, что при попытке переопределить функцию объявленную с () будет пердупреждение, что такая уже есть, а если без скобок - то никаких предупреждений не будет.

в скобках компилятор ожидает прототип увидеть, по идее.
а наличие/отсутствие скобок, видимо, и отличает inline/не-inline функции. 
От этого зависит когда будет вычисляться функция - на этапе компиляции или на этапе выполнения.

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

PS: а предупреждение выдается похоже вот почему:
если функция вычислялась на этапе компиляции, то все методы скомпилированные до переопределения этой функции и после ее переопределения будут использовать старое значение.



Это сообщение отредактировал(а) Ramirez - 6.10.2008, 19:13
PM ICQ   Вверх
ginnie
Дата 6.10.2008, 19:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Комодератор
Сообщений: 1287
Регистрация: 6.1.2008
Где: Москва

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



Ramirez, Вы верно указали ссылку, константы в perl представляют собой inline-функции. Inline-функция обязательно должна иметь прототип (), на это я и хотел обратить внимание.

Цитата

приведите подтверждение вашего ответа

  • Код

    perl -MO=Deparse -e 'sub const_test { 12 } warn "value is ", const_test;'

    sub const_test {
        12;
    }
    warn 'value is ', const_test();
  • Код

    perl -MO=Deparse -e 'sub const_test () { 12 } warn "value is ", const_test;'

    sub const_test () { 12 }
    warn 'value is ', 12;

  • Код

    perl -MO=Deparse -e 'sub const_test () { 12 } warn "value is ", &const_test;'

    sub const_test () { 12 }
    warn 'value is ', &const_test;





--------------------
Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям. (Мартин Фаулер. Рефакторинг)
PM MAIL Skype Jabber   Вверх
ginnie
Дата 6.10.2008, 19:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Комодератор
Сообщений: 1287
Регистрация: 6.1.2008
Где: Москва

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



Ramirez

Цитата

Визуально разница в том, что при попытке переопределить функцию объявленную с () будет пердупреждение, что такая уже есть, а если без скобок - то никаких предупреждений не будет.


если использовать use warnings, то предупреждение о переопределении будет в обоих случаях, для варианта с прототипом будет еще сообщение типа Prototype mismatch: sub main::test () vs none.

Цитата

а наличие/отсутствие скобок, видимо, и отличает inline/не-inline функции. 


это необходимое условие, но не достаточное, надо еще, чтобы тело функции после оптимизации и константных вычислений представляло собой константу, или лексическую переменную, на которую нет других ссылок.


--------------------
Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям. (Мартин Фаулер. Рефакторинг)
PM MAIL Skype Jabber   Вверх
GreenFactory
Дата 6.10.2008, 19:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(Ramirez @  6.10.2008,  18:51 Найти цитируемый пост)
от этого как раз зависит то, что константу нельзя переопределить...


К сожалению, у нас нет констант

Код

use strict;
use warnings;

use constant CONSTANT_TEXT => 'constant text';

print CONSTANT_TEXT, "\n";
{
    $SIG{__WARN__} = sub {};
    *CONSTANT_TEXT = sub () {'ups...'};
}
print CONSTANT_TEXT, "\n";
eval 'print CONSTANT_TEXT, "\n"';

PM MAIL   Вверх
KSURi
Дата 6.10.2008, 20:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(GreenFactory @  6.10.2008,  19:51 Найти цитируемый пост)
К сожалению, у нас нет констант

use Readonly::XS


--------------------
Died at Life.pl line 21
PM Jabber   Вверх
GreenFactory
Дата 7.10.2008, 19:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(KSURi @  6.10.2008,  20:26 Найти цитируемый пост)
use Readonly::XS 

На каждую хитрую ж....
Найдётся достойный ответ smile 
"А Readonly, что он, всего лишь делает SvREADONLY_on() если все же припекло. Что интереснее, что некоторым вещам можно делать SvREADONLY_off()"
Написано тут
Из этого следует, что если уж приспичит поменять, поменяют...
Следовательно, у нас нет констант.
PM MAIL   Вверх
ginnie
Дата 7.10.2008, 22:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Комодератор
Сообщений: 1287
Регистрация: 6.1.2008
Где: Москва

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



GreenFactory, если Вы смотрели модуль Readonly.pm, то он использует макрос SvREADONLY только для скаляров и только при установленном модуле Readonly::XS, во всех остальных случаях используется связывание (tie) smile

Если под константой понимать значение, вычисляемое и подставляемое при компиляции, то у нас есть константы  smile 


--------------------
Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям. (Мартин Фаулер. Рефакторинг)
PM MAIL Skype Jabber   Вверх
GreenFactory
Дата 13.10.2008, 20:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(ginnie @  7.10.2008,  22:16 Найти цитируемый пост)
Если под константой понимать значение, вычисляемое и подставляемое при компиляции, то у нас есть константы

Из википедии:
Конста́нта (от лат. constans - постоянный, неизменный) — некоторая величина, не изменяющая своё значение в рамках рассматриваемого процесса.

Из этого утверждения следует, что если я изменил "константу", то она автоматом перестаёт ей быть.

А на счёт tie и SvREADONLY
SvREADONLY надёжнее, т.к. untie есть в чистом перле, а SvREADONLY_off только в XS.

PM MAIL   Вверх
ginnie
Дата 13.10.2008, 21:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Комодератор
Сообщений: 1287
Регистрация: 6.1.2008
Где: Москва

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



GreenFactory, Вы не изменяете константу, Вы подменяете понятие константы на понятие вызова функции. В Perl они похожи, но это не одно и тоже  smile и интерпретатор четко видит разницу!

Вот Ваш пример с eval(), после perl -MO=Deparse

Код

use constant ('CONSTANT_TEXT', 'constant text');
use warnings;
use strict 'refs';
print 'constant text', "\n";
{
    $SIG{'__WARN__'} = sub {
        
    };
    *CONSTANT_TEXT = sub () { 'ups...' };
}
print 'constant text', "\n";
eval 'print CONSTANT_TEXT, "\\n"';


где интерпретатору и мне очевидно, где константы ('constant text'), а где вызов функции (CONSTANT_TEXT).
Соглашусь, что есть конструкции, где константы использовать технически невозможно (типа eval('code')).



--------------------
Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям. (Мартин Фаулер. Рефакторинг)
PM MAIL Skype Jabber   Вверх
GreenFactory
Дата 13.10.2008, 22:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(ginnie @  13.10.2008,  21:14 Найти цитируемый пост)
Вы подменяете понятие константы на понятие вызова функции.

Ничего такого, моё представление о константах можно назвать классическим.
Цитата(ginnie @  13.10.2008,  21:14 Найти цитируемый пост)
В Perl они похожи, но это не одно и тоже

Как раз в Perl это одно и тоже. 
Вызов функции, подпадающее под некоторые условия, заменяется на результат её выполнения при компиляции.
Этой побочной фишкой функций и решили воспользоваться для констант.
Цитата(ginnie @  13.10.2008,  21:14 Найти цитируемый пост)
интерпретатор четко видит разницу!

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

Немного подправил пример.
Код

use constant CONSTANT_TEXT => 'constant text';
print CONSTANT_TEXT, "\n";
use ups;
print CONSTANT_TEXT, "\n";
eval 'print CONSTANT_TEXT, "\n"';

и
Код

package ups;
BEGIN
{
    $SIG{__WARN__} = sub {};
    *CONSTANT_TEXT = sub () {'ups...'};
}


PM MAIL   Вверх
ginnie
Дата 13.10.2008, 22:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Комодератор
Сообщений: 1287
Регистрация: 6.1.2008
Где: Москва

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



GreenFactory, новый пример у меня выводит

Код

constant text
constant text
constant text


а у Вас что?


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


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

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


 




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


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

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