![]() |
|
Модераторы: korob2001, ginnie |
![]()
|
|
| Logo |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 694 Регистрация: 22.7.2008 Репутация: 3 Всего: 10 |
Есть ли в Perl возможность поддержки упорядоченых хешей (в порядке вставки пар ключ значения), так что бы создаваемые через конструкцию {} хеши поддерживали порядок?.
Т.е. если в программе
То хеши создавались с помощью одного из Tie модулей, поддерживающих порядок пар ключ значение, например Tie::InsertOrderHash или Tie::Hash::Indexed. |
|||
|
||||
| Pfailed |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 933 Регистрация: 19.7.2009 Репутация: 22 Всего: 39 |
Простого способа не знаю.
Проще записать немного иначе
А в подпрограмме "o" сделать нужные tie. |
|||
|
||||
| DurRandir |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 335 Регистрация: 27.9.2009 Репутация: 14 Всего: 17 |
Частично да. Можно написать xs модуль, в котором переопределить pp_anonhash. Это даст возможность создавать что угодно вместо {}, но вот с не-ссылочными хэшами вида %a=() ничего не выйдет.
Это сообщение отредактировал(а) DurRandir - 16.6.2012, 16:31 |
|||
|
||||
| Logo |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 694 Регистрация: 22.7.2008 Репутация: 3 Всего: 10 |
DurRandir,
%hash не обязательно. А готовый модуль в Perl для этого есть? XS и perl компиляция тема довольно сложная, как я понимаю... |
|||
|
||||
| DurRandir |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 335 Регистрация: 27.9.2009 Репутация: 14 Всего: 17 |
>Logo
Увы - здесь требуется подменять внутренности перла. |
|||
|
||||
| Logo |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 694 Регистрация: 22.7.2008 Репутация: 3 Всего: 10 |
DurRandir
Есть модули для ограничения опкодов (Opcode, Safe, ops), но они лишь выдают ошибку, если используется запрещенный опкод. А как преобразовать опкоды? |
|||
|
||||
| DurRandir |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 335 Регистрация: 27.9.2009 Репутация: 14 Всего: 17 |
Не преобразовывать. В том то и дело. Менять optree можно даже из перла (B::Generate и компания), а здесь требуется поменять способ выполнения инструкции.
Если действительно интересно (хотя, по мне, с нуля начинать разбираться в этом будет дороже решения от Pfailed) - то берётся исходник перла (скорее всего, подойдёт любая версия, но лучше своего), оттуда выдирается код pp_anonhash, копируется к себе. Меняем создание hv+запись в него на вызов конструктора Tie::Whatever и вызовы его методов для записи. Это наш новый опкод. Теперь его надо установить - делается присвоением ссылки на него в PL_ppaddr[OP_ANONHASH]. Проблема в том, что при таком способе, "помнящие" хэши будут создаваться для любого перлового кода, в любом модуле, что приведёт к значительному снижению скорости работы. Поэтому нужна будет дополнительная работа по "разметке" того, где применять новую версию, а где - старую. Можно сделать, к примеру, через B::Hooks::OP::Check и проверку PL_compiling. В общем, это не очень простой способ) |
|||
|
||||
| Logo |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 694 Регистрация: 22.7.2008 Репутация: 3 Всего: 10 |
Почему? По идее, преобразовать optree {...args...} в optree Package::sub(...args...) Мдя. Мне кажется, или проще добавить поддержку упорядоченности в сам perl? Смотрю, судя по всему за хеш таблицу частично отвечает x2p/hash.c Правда методов next там нет, только store, fetch, new. Хотя поле hent_next в hentry есть, есть и "HENT *tbl_eiter; /* current entry of iterator */". Видимо с ними работает другой код. P.S. Жаль конечно что об этом не позаботились разработчики. |
|||
|
||||
| DurRandir |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 335 Регистрация: 27.9.2009 Репутация: 14 Всего: 17 |
>преобразовать optree {...args...} в optree Package::sub(...args...)
B::Generate в помощь) Разработчики то позаботились, просто вы хотите подменить базовую структуру данных своей - это даже для них слишком) |
|||
|
||||
| Logo |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 694 Регистрация: 22.7.2008 Репутация: 3 Всего: 10 |
Я о том, что в этой самой базовой структуре не реализовали выбор значений по порядку вставки. P.S. пропатчить его мне оказалось не так-то просто. |
|||
|
||||
| TP@MB@Y |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 370 Регистрация: 18.12.2004 Где: Москва Репутация: нет Всего: 4 |
Хэш - неупорядоченный список пар, поэтому встроенного решения нет.
Эффективность решение вашей проблемы сильно зависит от ответа на вопрос: как вы планируете работать с этим хэшом? (после его заполнения) |
|||
|
||||
| Logo |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 694 Регистрация: 22.7.2008 Репутация: 3 Всего: 10 |
Это понятно, собственно и вопрос, как сделать так, что бы конструкция {} возвращала не HashMap, а LinkedHashMap, если проводить аналогию с Java. |
|||
|
||||
| TP@MB@Y |
|
||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 370 Регистрация: 18.12.2004 Где: Москва Репутация: нет Всего: 4 |
|
||||
|
|||||
| Logo |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 694 Регистрация: 22.7.2008 Репутация: 3 Всего: 10 |
Все стандартные функции perl хеша (each, получение/установка значения) с той лишь разницей, что пары хранятся в порядке их добавления в хеш. Хеш передается по ссылке в другой модуль, а там действия обрабатываются в порядке их добавления в хеш. Дополнительные функции для ручной сортировки в принципе не нужны. Так же не является критичной производительность, простые perl скрипты.
|
|||
|
||||
| TP@MB@Y |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 370 Регистрация: 18.12.2004 Где: Москва Репутация: нет Всего: 4 |
допустим, что у вас система спроектирована правильно и вам действительно нужны "упорядоченные" хэши
вот самые простые варианты, которые приходят сразу в голову: 1) при добавлении нового ключа задавать некий порядковый номер для значения (например timestamp), после чего уже в foreache'e пробегать по отсортированным парам по этому порядковому номеру 2) написать простой класс, реализующий ваши требования (например, при добавлении нового ключа, последний будет добавляться в список ключей, а сам хэш будет лежать рядышком) 3) найти на CPAN'e модуль, который это реализует, разобраться как он работает. Беглым взгядом нашел вот это - http://search.cpan.org/~ovid/Array-AsHash-...Array/AsHash.pm (вроде именно то что вам нужно) |
|||
|
||||
![]()
|
| Правила форума "Perl" | |
|
|
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, korob2001, sharq. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Perl: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |