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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Хеш с упорядочеными ключами по умолчанию в Perl 
:(
    Опции темы
Logo
Дата 16.6.2012, 02:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Есть ли в Perl возможность поддержки упорядоченых хешей (в порядке вставки пар ключ значения), так что бы создаваемые через конструкцию {} хеши поддерживали порядок?.
Т.е. если в программе
Код

$hash =  {
  foo => {
    bar => 1,
    baz => 2,
  }
}

То хеши создавались с помощью одного из Tie модулей, поддерживающих порядок пар ключ значение, например Tie::InsertOrderHash или Tie::Hash::Indexed.
PM MAIL   Вверх
Pfailed
Дата 16.6.2012, 08:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Простого способа не знаю.
Проще записать немного иначе
Код

$hash =  o (
  foo => o (
    bar => 1,
    baz => 2,
  )
)


А в подпрограмме "o" сделать нужные tie.



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


Опытный
**


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

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



Частично да. Можно написать xs модуль, в котором переопределить pp_anonhash. Это даст возможность создавать что угодно вместо {}, но вот с не-ссылочными хэшами вида %a=() ничего не выйдет.

Это сообщение отредактировал(а) DurRandir - 16.6.2012, 16:31
PM   Вверх
Logo
Дата 16.6.2012, 19:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



DurRandir,
%hash не обязательно. А готовый модуль в Perl для этого есть? XS и perl компиляция тема довольно сложная, как я понимаю...
PM MAIL   Вверх
DurRandir
Дата 16.6.2012, 23:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



>Logo
Увы - здесь требуется подменять внутренности перла. 
PM   Вверх
Logo
Дата 17.6.2012, 18:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



DurRandir
Есть модули для ограничения опкодов (Opcode, Safe, ops), но они лишь выдают ошибку, если используется запрещенный опкод. А как преобразовать опкоды?
PM MAIL   Вверх
DurRandir
Дата 17.6.2012, 19:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 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. 

В общем, это не очень простой способ)
PM   Вверх
Logo
Дата 18.6.2012, 02:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 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. Жаль конечно что об этом не позаботились разработчики.
PM MAIL   Вверх
DurRandir
Дата 18.6.2012, 14:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



>преобразовать optree {...args...} в optree Package::sub(...args...)
B::Generate в помощь)

Разработчики то позаботились, просто вы хотите подменить базовую структуру данных своей - это даже для них слишком)
PM   Вверх
Logo
Дата 24.6.2012, 20:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата

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


Я о том, что в этой самой базовой структуре не реализовали выбор значений по порядку вставки.

P.S. пропатчить его мне оказалось не так-то просто.
PM MAIL   Вверх
TP@MB@Y
Дата 17.7.2012, 12:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Хэш - неупорядоченный список пар, поэтому встроенного решения нет.

Эффективность решение вашей проблемы сильно зависит от ответа на вопрос:
как вы планируете работать с этим хэшом? (после его заполнения)

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


Опытный
**


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

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



Цитата

Хэш - неупорядоченный список пар, поэтому встроенного решения нет.


Это понятно, собственно и вопрос, как сделать так, что бы конструкция {} возвращала не HashMap, а LinkedHashMap, если проводить аналогию с Java.
PM MAIL   Вверх
TP@MB@Y
Дата 23.7.2012, 09:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(Logo @  20.7.2012,  17:32 Найти цитируемый пост)
Это понятно, собственно и вопрос, как сделать так, что бы конструкция {} возвращала не HashMap, а LinkedHashMap, если проводить аналогию с Java. 




Цитата(TP@MB@Y @  17.7.2012,  12:16 Найти цитируемый пост)
Эффективность решение вашей проблемы сильно зависит от ответа на вопрос:
как вы планируете работать с этим хэшом? (после его заполнения)


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


Опытный
**


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

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



Все стандартные функции perl хеша (each, получение/установка значения) с той лишь разницей, что пары хранятся в порядке их добавления в хеш. Хеш передается по ссылке в другой модуль, а там действия обрабатываются в порядке их добавления в хеш. Дополнительные функции для ручной сортировки в принципе не нужны. Так же не является критичной производительность, простые perl скрипты.
PM MAIL   Вверх
TP@MB@Y
Дата 24.7.2012, 08:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



допустим, что у вас система спроектирована правильно и вам действительно нужны "упорядоченные" хэши

вот самые простые варианты, которые приходят сразу  в голову:

1) при добавлении нового ключа задавать некий порядковый номер для значения (например timestamp), после чего уже в foreache'e пробегать по отсортированным парам по этому порядковому номеру

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

3) найти на CPAN'e модуль, который это реализует, разобраться как он работает. Беглым взгядом нашел вот это - http://search.cpan.org/~ovid/Array-AsHash-...Array/AsHash.pm (вроде именно то что вам нужно)
PM   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Perl"
korob2001
sharq
  • В этом разделе обсуждаются общие вопросы по языку Perl
  • Если ваш вопрос относится к системному программированию, задавайте его здесь
  • Если ваш вопрос относится к CGI программированию, задавайте его здесь
  • Интерпретатор Perl можно скачать здесь ActiveState, O'REILLY, The source for Perl
  • Справочное руководство "Установка perl-модулей", можно скачать здесь


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

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


 




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


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

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