LINUX.ORG.RU

#!perl

use strict;
use warnings;

my @ponies =
    qw/ rarity rainbow fluttershy twilight pinkie applejack /;

print my $ponies = @ponies;

Это называется динамическое сопоставление типов. Вот это тебя может удивить:

#!perl

use strict;
use warnings;

my %pirates = (
    "Cpt. Jack" => 1,
    "Ehhhh" => 1,
);

print my $pirates = %pirates;

gh0stwizard ★★★★★
()
Последнее исправление: gh0stwizard (всего исправлений: 1)
Ответ на: комментарий от KennyMinigun

А что эти числа означают? (хеш в скалярном контексте)

Лучшее объяснение описано здесь: http://stackoverflow.com/questions/7427381/what-do-you-get-if-you-evaluate-a-...

Хэш это ассоциативный массив. Хэш-функция конвертирует ключ в число в качестве индекса элемента списка («bucket»), для которого записывается значение. Несколько ключей могут иметь одинаковый индекс (коллизия), ассоциативный массив учитывает данный случай.

Деноминатор (последнее число) указывает на общее количество «buckets». Аналог $count = () = %hash

Нумератор (первое число) число «buckets», которые имеют один или более элементов.

Для хэшей, у которых кол-во ключей равно кол-ву элементов, чем первое число больше, тем лучше. Например, 6/8 имеет меньше коллизий, чем 4/8.

Подробная статья о хэшах в перле: http://www.perl.com/pub/2002/10/01/hashes.html

P.S. Если много раз запускать скрипт выше, то можно заметить как первое число меняется от запуска к запуску.

gh0stwizard ★★★★★
()
Последнее исправление: gh0stwizard (всего исправлений: 1)

Ну и поскольку пример ТС не очень юзабельный, в практике я использую такое:

if (@array == 1) {
  ...
} elsif (@array < 5) {
  ...
} else {
  ...
}

И подобное часто встречается в хороших модулях, чаще всего для @_: @_ > 4 and croak("Too many arguments").

gh0stwizard ★★★★★
()
Последнее исправление: gh0stwizard (всего исправлений: 1)

И таки воистину велик. Вот бы еще пошустрее был и память не жрал невосполнимо — цены бы ему не было.

arturpub ★★
()
Ответ на: комментарий от arturpub

Для методов ОО-классов прототипы не работают, раз. Во-вторых, прототипы не работают для разных файлов/модулей. Три прототипы это лишь хинт для тех, кто решил ковырятся в коде. Т.е, вот такая недоработка перла, но ее пытаются исправить, вроде в 5.20 обещали <что-то там> сделать в этом направлении. Итого, прототип работает как прототип только когда вызов прототипной функции исходит из того же файла, но не для ОО-методов. Или иначе, проверка прототипа срабатывает только на этапе компиляции, рантайм в пролете. И вообще, Перл это не Си :)

gh0stwizard ★★★★★
()
Последнее исправление: gh0stwizard (всего исправлений: 1)
Ответ на: комментарий от gh0stwizard

Аа, а то я в своих велосипедах ооп не юзаю. А между модулями разве не работает? Я вроде так делал, хотя может там просто нет варнинга что нет проверки...

arturpub ★★
()
Ответ на: комментарий от gh0stwizard
my %args = @_ ^ 1 ? %{ $_[0] } : @_;

Позволяет

my_sub(key => 'value');
# и
my_sub({ key => 'value' });

Естественно нужны еще проверки. Но суть отображена.

KennyMinigun ★★★★★
()
Ответ на: комментарий от anonymous

в краци

желаю, чтоб тебя в аду сто тысяч Розенталей ебали в анус кочергой

anonymous
()
Ответ на: комментарий от arturpub

А между модулями разве не работает?

Нет. Т.к. каждый модуль/файл компилируется один раз. Проверка прототипа функции из другого модуля не делается.

Я вроде так делал, хотя может там просто нет варнинга что нет проверки...

Можешь сам убедится. Например:

#!perl

use strict;
use warnings;

use JSON;

# prototype sub to_json ($@)
print to_json({"proto?" => "no, sorry"});

print &JSON::to_json(); # undefined behavior

{"proto?":"no, sorry"}
hash- or arrayref expected (not a simple scalar, use allow_nonref to allow this) at JSON.pm line 154.

Последняя строчка это ошибка от JSON::XS или JSON::PP (см. sub PP_encode_json {).

gh0stwizard ★★★★★
()
Ответ на: комментарий от KennyMinigun

Позволяет

Игра с аргументами может делать фантастические вещи. Особенно через pop, splice. Но твой вариант лишает смысла использовать ссылки, ибо они всеравно дополнительно заолакейтят столько же места, сколько оригинал. ИМХО, пример гкода :) Без обид.

Аналог, без избыточного копирования:

#!perl

use strict;
use warnings;

use Data::Dumper;

sub my_sub {
  my $args = @_ > 1 
      ? { @_ } : ref $_[0] eq 'HASH' 
         ? $_[0] : die "Invalid arguments passed";

  print Dumper $args;
}

my_sub(test => 1);
my_sub({1=>2, 3=>4});

gh0stwizard ★★★★★
()
Последнее исправление: gh0stwizard (всего исправлений: 2)
Ответ на: комментарий от gh0stwizard

Поддакну :)

Я когда на питоне сидел все нетривиальные интерфейсы все равно вырождались в *args, **kvargs. А в перле проверил чо там и вперед.

arturpub ★★
()
Ответ на: комментарий от gh0stwizard

Но твой вариант лишает смысла использовать ссылки, ибо они всеравно дополнительно заолакейтят столько же места, сколько оригинал.

Да, но оверхед (без рекурсии) незначителен, чтоб им заморачиваться экономией на спичках.

  my $args = @_ > 1 
      ? { @_ } : ref $_[0] eq 'HASH' 
         ? $_[0] : die "Invalid arguments passed";

And we need to go deeper... Хотел написать еще тернарок вложенных, потом понял, что вечером в пятницу я перл весь забыл :)

KennyMinigun ★★★★★
()
Ответ на: комментарий от KennyMinigun

Да, но оверхед (без рекурсии) незначителен, чтоб им заморачиваться экономией на спичках.

Все зависит от назначения функции, а также может она кидать эксепшены или нет. И то, как она реагирует на невалид. В «Совершенном коде» написано, что обработка ошибок может достигать 90% всего кода. Твой вариант соблазнителен кратостью. И он подходит для ряда случаев. Но я бы предпочел для последних такое: my %args = @_; Изучая си, я понимаю, что перл итак очень краток =)) Даже три строчки выше делают дофига работы.

Вообще, перловая обработка переменных функций тянется с фортрана?. И такая реализация, имхо, наоборот упрощает многие вещи.

Вот чтиво: http://sydney.edu.au/engineering/it/~sholden/pythonperl.html Функция sub soundex божественна :)

gh0stwizard ★★★★★
()
Ответ на: комментарий от KennyMinigun

приведи пример задачи, когда это необходимо)

anonymous
()
Ответ на: комментарий от KennyMinigun

TCL:

% proc =()= {v} {return [llength $v]}
% set ponies {rarity rainbow fluttershy twilight pinkie applejack}
% =()= $ponies
% 6

anonymous
()
Ответ на: комментарий от KennyMinigun

А кто вычислять количество будет? :)

Я уже вычислил, шесть их. :)

proud_anon ★★★★★
()
Flaming X-Wing =<>=~

Discovered by Philippe Bruhat, 2007.

что это значит? Discovered by....

это то что я думаю? o_O

dikiy ★★☆☆☆
()
Ответ на: комментарий от dikiy

что это значит? Discovered by....

Perl — это как древнее критское письмо, его приходится исследовать, открывать там новые операторы, писать научные статьи о значении отдельных строк в различных скриптах, гуляющих по сети...

proud_anon ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.