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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Анонимные функции и прототипы 
:(
    Опции темы
Logo
Дата 17.7.2009, 12:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Можно ли использовать прототипы с аноноимнными функциями? С одной стороны, записать анонимную функцию с прототипом дозволяется, с другой - как сделать так, чтобы он работал я так и не понял.
PM MAIL   Вверх
arto
Дата 19.7.2009, 10:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1495
Регистрация: 31.10.2004

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



пример?
PM MAIL ICQ   Вверх
Logo
Дата 19.7.2009, 11:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Код

#!/usr/bin/perl

$fnc = sub ($$) {print @_};

&$fnc(1,2,3); #не происходит ошибки, выводит 123
$fnc->(1,2,3); #так тоже
*fnc = $fnc;
fnc(1,2,3);  #и так не помогает

Вот пример. Как ни пробую, прототип анонимной функции не работает, хотя компилятором принимается.
PM MAIL   Вверх
arto
Дата 19.7.2009, 16:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1495
Регистрация: 31.10.2004

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



проверка прототипов происходит во время компиляции.
PM MAIL ICQ   Вверх
Logo
Дата 19.7.2009, 16:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



А зачем тогда разрешается указывать прототипы в анонимных функциях?
Кстате так тоже не работает
Код

#!/usr/bin/perl

BEGIN {
$fnc = sub ($$) {print @_};
}
&$fnc(1,2,3); #не происходит ошибки, выводит 123
$fnc->(1,2,3); #так тоже
*fnc = $fnc;
fnc(1,2,3);  #и так не помогает

PM MAIL   Вверх
sir_nuf_nuf
Дата 20.7.2009, 09:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



прототип привязан к имени функции. Т.е. проверка и преобразование агрументов к прототипу происходит на этапе лексического анализа.. (это хак если желаете).

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

Вообщем прототипы - довольно редко бывают необходимы.


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


Опытный
**


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

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



Жаль :(
PM MAIL   Вверх
sir_nuf_nuf
Дата 21.7.2009, 13:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Logo, чего вам жаль ?
прототипы - это НЕ средство типизации. Перлу они не нужны (по задумке =))
прототипы полезны когда вы хотите дописать функционал на уровне близком к синтаксическому анализу..
т.е. расширить язык. 

Например, вы хотите передавать массив по ссылке, но что бы для пользователя это было красиво (как в push/pop), или хотите передавать ссылку на процедуру, но что бы пользователь писал ее просто как блок кода. Вот тут то и нужны прототипы.

Код

sub do_push (\@;@) {
  my ($ar, @stuff) = @_;
  push @$ar, @stuff;
  return scalar @stuff;
}
do_push @a, @b;  #заметьте @a, а не \@a


См.. Error.pm


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


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


Опытный
**


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

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



Вообще-то прототипы предназначены для того, чтобы передавать аргументы как в нормальных языках программирования, т.е. обязательные/необязательные параметры, функция сама знает, взять ей аргумент по ссылке или по значению.
PM MAIL   Вверх
sir_nuf_nuf
Дата 23.7.2009, 10:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Logo, 
Цитата(Logo @  22.7.2009,  23:11 Найти цитируемый пост)
как в нормальных языках 
 .. это наезд на perl ?  smile 

Цитата(Logo @  22.7.2009,  23:11 Найти цитируемый пост)
функция сама знает, взять ей аргумент по ссылке или по значению. 

Да, это конечно. Функция обязана знать что ей передают. Прототипы только меняю способ синтаксиси передачи параметров.

Обязательные /  необязательные.. опять таки - это того нет по задумке в перле. Все - необязательные.


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


Опытный
**


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

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



Цитата

Обязательные /  необязательные.. опять таки - это того нет по задумке в перле. Все - необязательные.


Если какие-то параметры не используются логично сделать их не обязательными, ведь в случае прототипов для этого лишних телодвижений не нужно.

Цитата

Прототипы только меняю способ синтаксиси передачи параметров.

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

Самое обидное же, что хотя прототипы  в анонимных функциях не работают, их там почему-то можно записать, что оставляет ощущение недоделанности языка.
PM MAIL   Вверх
sir_nuf_nuf
Дата 24.7.2009, 15:52 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(Logo @  24.7.2009,  13:43 Найти цитируемый пост)
Если какие-то параметры не используются
 их надо удалить (см. Фаулер, Рефакторинг). =)


Цитата(Logo @  24.7.2009,  13:43 Найти цитируемый пост)
Ну да, было бы удобно и привычно написать переменную массива, а функция уже сама взяла ссылку, как в остальных языках.

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


Цитата(Logo @  24.7.2009,  13:43 Найти цитируемый пост)
оставляет ощущение недоделанности языка. 

 smile У меня perl зачастую вызывает ощущение переделанности =)

А еще в нем можно писать так
Код

my SomeClass $object = SomeClass->new(...);

нафиг надо - тоже не ясно..


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


Опытный
**


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

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



Цитата(sir_nuf_nuf @  24.7.2009,  15:52 Найти цитируемый пост)
Если какие-то параметры не используются
 их надо удалить (см. Фаулер, Рефакторинг). =)


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


Цитата

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


Ну да - при вызове не надо к примеру писать \ перед переменной - то что функция берет его по ссылке известно из ее обявления, как во всех остальных языках.

Цитата

 У меня perl зачастую вызывает ощущение переделанности =)

А еще в нем можно писать так
Выделить всёкод Perl
1:
    
my SomeClass $object = SomeClass->new(...);

нафиг надо - тоже не ясно.. 


Я включение возможности, которая не работает (сабж), иначе как недоработку не вижу.
PM MAIL   Вверх
mvsgt
Дата 27.7.2009, 11:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Мой опыт показал, что от прототипов много проблем. Гораздо продуктивней использовать модули - валидаторы, например MooseX::Params::Validate или Params::Validate . Это менее производительно, но во многих отношениях лучше, так как происходит использование функций в более явном виде и без странных преобразований.
PM MAIL   Вверх
sir_nuf_nuf
Дата 27.7.2009, 11:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



mvsgt, +1 - я же и говорю - прототипы не для бизнес логики, а для расширений языка.

Кстати, я думаю, что при проектировании программ нужно учитывать идеологию языка.
То что в перле слабая типизация - намекает на то, что не нужно писать процедуры сильно завязанные на типы. Нужно писать такие которые работают с _простыми_ данными. Вообще стараться
избегать сложных абстракций.

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

Ну к примеру.. функция которая собирает url из частей.
можно написать так:
Код

sub make_http_url ($$;\@$$) {my ($host, $path, $params, $port, $anchor) = @_; bla bla bla}

и тогда программер пока не выучит как ее вызывать каждый раз будет смотреть документацию.. а еще скорее - код, потому, что прототип ($$;\@$$) ничего не говорит ему. Почему это порт идет после параметров запроса ? а потому что юзается редко и что бы не писать каждый раз undef..


Можно так:
Код

=pod
usage: make_http_url(host => 'host', port => 'port', ...)
=cut
sub make_http_url {my %data = @_; return "$data{host}" . bla bla bla}

передача через хеш - запоминается быстрее. А если прогер затупил и забыл передать путь - это он узнает через die.

Если количество параметров становится громадным или его сложно описать в одной строчке - нужно создавать классы.  При таком подходе программеру будет просто неудобно использовать код неправильно.

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


--------------------
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.0620 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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