2010-08-02 2 views
2

У меня есть серия Moose объектов, которые я ищу для подачи на JSON::XS путем Catalyst::View::JSON. JSON :: XS не может кодировать блаженные структуры данных. Я знаю, что есть MooseX::Storage::Format::JSON, который может - своего рода - делать то, что я хочу; но, кажется, слишком тяжело. Я ищу, по сути, ту же информацию, что и XXX.pm. Я просто хочу, чтобы структуры raw-data рекурсивно не прерывались, поэтому JSON::XS (драйвер для JSON::Any, который использует C:V:JSON), может отображать его.Как включить объекты Moose в JSON для использования в Catalyst?

Каков наилучший способ использования Catalyst::View::JSON и JSON::XS с Moose объектов? Кажется, у меня есть четыре очевидных варианта:

  1. Make Catalyst::View::JSON работы с Moose объектов, с помощью заплат C:V:JSON читать из freeze и завершить запрос, если аргумент подвергается является Moose Object.
  2. Патч JSON::XS для возврата назад $obj->freeze if $obj->isa('Moose') && $obj->does('MooseX::Storage::Format::JSON'). Я должен смотреть в MX:S:F:JSON, чтобы убедиться, что класс, используемый JSON::Any, и по доверенности MX:S:F:JSON, является JSON::XS (ненавидит думать о изобилии ошибки, если JSON::Any выбирает другой внутренний кодер для объекта Муса, что JSON::XS называется использовать.
  3. Выяснить, как рекурсивно лишат и пусть Catalyst::View::JSON делать свое дело.
  4. не используйте Catalyst::View::JSON вообще. Просто напишите STDOUT $obj->freeze и вручную завершить запросы .. Это кажется наиболее хаком.

I Конечно, есть и другие варианты, любые идеи ? Какой у меня лучший выбор?

+0

Я записываю [отчет об ошибке на rt для 'C: V: JSON'] (https://rt.cpan.org/Ticket/Display.html?id=60564&results = af4f9b8bf7a79ca52896b9b59dbf480a) только для записи. –

ответ

0

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

use JSON::Syck; 
use URI; 
use feature ':5.10'; 
say JSON::Syck::Dump(
bless { foo => URI->new("http://www.evancarroll.com") } 
) 

Я написал автору о JSON::XS он не игра для добавления функциональности.Вот некоторые из текста (вырвано из контекста из многочисленных сообщений, чтобы показать, почему эта функция не существует) от Marc Lehmann в формате JSON :: XS сопровождающим:

Нет, потому что вы используете JSON и не Perl. Perl, очевидно, способен представлять любые данные Perl структура, но JSON нет, поэтому вы должны указать, что делать. Многие люди наивно запрашивают что-то вроде «просто дамп структуры данных», но JSON даже не может представлять все структуры данных, не являющиеся объектами, .

...

Ваш вопрос так: почему я не могу послать этот 1MB Jpeg изображение как текстовый файл - просто потому, что ASCII не может представлять октета.

...

Или, может быть, вы justw муравья бросить некоторый мусор на него и ожидать JSON :: XS делать то, что хорошо для вас (но неправильно для других людей) - есть просто нет способ для JSON :: XS магически угадать что вы хотите.

...

TO_JSON это. Все остальное просто дикое угадывание.

...

Тогда, возможно, вы должны попробовать вещи, которые JSON фактически может представлять. Бросив некоторый объект иерархию на него, и в надежде это будет делать «правильные вещи» является явно плохо программной инженерии - попробуйте не прибегать хак, когда ваш protocl требует JSON, а затем отправить JSON, не ожидать JSON библиотеку, чтобы исправить ваше недопустимое сообщение .

Я не знаю, как ответить на это, кроме Я НЕ УХОДЯ. ПРОСТО РАБОТАЙ! LIKE :: SYCK. Я не ожидаю, что объекты будут отлично преобразованы в JSON. Но, я думаю, я попадаю в 80%, что просто хочу, чтобы он работал. Я использую JSON для импорта jQuery, не выполняющего банковских операций во время операции на головном мозге. В конечном счете, я не хочу использовать особую роль ... Я хочу, чтобы все, что было послано к нему, было изменено для меня до уровня, который делает его полезным в ответ на запрос JQuery JSON.

UPDATE

К сожалению, я пропустил эти ответы, пока кто-нибудь не сказал, что я троллинг в неродственной среде. MooseX :: Storage не работает для классов, отличных от Moose, мне нужен общий способ представления stash в формате JSON. К сожалению, некоторые из этих членов тайника являются объектами Муз. XML :: Simple может это сделать, Data::Dumper может сделать это, JSON :: Syck может это сделать, список можно продолжить - я просто хочу, чтобы это было сделано. Это не должно быть 1: 1 с Perl, и, честно говоря, я хочу, чтобы это было сделано довольно близко к тому, как это делается JSON::Syck. Мой аргумент здесь: «Как мне получить JSON::XS для работы точно так же, как JSON::Syck в настоящее время?» И ваш ответ - вы не можете.Поэтому я не использовал другое решение. Написание кода стоит денег, почему я хочу написать to_JSON, если Syck уже делает это правильно ... Я хотел бы сказать, что бремя лежит на nay-sayers, чтобы показать, что Syck сериализует мода, которая нежелательна. Кроме того, имейте в виду, что JSON::Syck был посеян Audry, который ни в коем случае не является троллем, идиотом или «поврежден мозгом»; или любые другие термины, которые меня бросают. Я остановлюсь на этом: отсутствие плохой сериализации маршрута JSON::Syck и желаемый результат уже just-working заставляет меня полагать, что это хороший выбор для меня. И что может сделать MooseX :: *: JSON по-другому с произвольным объектом Moose? Почему, по вашему мнению, код не может быть записан для принятия объекта Moose, а не метода на нем? Если вы считаете иначе, ответьте на что-то существенное - я бы хотел увидеть лучший ответ. Благодарю. (направленный на @jrockway и @Ether)

+6

Lehmann точно прав. И теперь я знаю, почему он так ненавидит пользователей. Вы действительно не понимаете, откуда он? Некоторые вещи в Perl не могут быть представлены как JSON. Вместо того, чтобы гадать, JSON :: XS требует, чтобы вы сделали преобразование. MooseX :: Storage - это модуль, который преобразует классы Moose в то, что может быть представлено как JSON. – jrockway

+2

«Я не знаю, как отреагировать на это, кроме того, что я НЕ УХОДИТ. ПРОСТО РАБОТА!» Разве вы не программист? Это ваша работа, чтобы «просто работать». Наличие «модулей инфраструктуры» делает случайное угадывание, которое работает некоторое время, возможно, может быть, похоже на то, что они делали бы в зале с использованием языка Gemstone, вдохновленного Perl. Звучит разочаровывающе! –

+2

«Я хочу, чтобы все, что было послано к нему, было изменено для меня до уровня, который делает его полезным в ответ на запрос JQuery JSON». Вы вообще не видели MooseX :: Storage? –

4

Если вы не заботитесь о том, чтобы полностью освободить свой объект и сделать его полностью непригодным (с точки зрения Муса), попробуйте unbless от Data::Structure::Util.

Я лично предпочитаю MooseX::Storage для более элегантного и устойчивого решения.

+1

Moose только когда-либо гарантировал, что это будет работать в случае по умолчанию. MooseX :: GlobRef или MooseX :: NonMoose сделает это решение менее оптимальным для некоторых случаев. – perigrin

+0

@perigrin !! upvoted, мне нужна функциональность MooseX :: GlobRef раньше, я могу использовать это сегодня вместо некоторого ad-hoc-кода для записи файла :: Stat до того, как файл был открыт –

+0

@rodigo, в то время как хорошая идея это не делает Не работай. 'unbless (URI-> new ('http://foobar.com'))', возвращает скалярную ссылку '\" http://www.foobar.com ", которую' JSON :: XS' не может проанализировать 'не может кодировать ссылку на скалярный http://www.foobar.com ', если скаляр не равен 0 или 1 на -e строке 1.' –

5

Я, как правило, делаю вариант 3 с помощью MooseX :: Storage, чтобы предоставить метод pack(), который возвращает структуру данных Perl, которую я могу использовать в своем кошельке, чтобы View мог отображать его по своему усмотрению.

Также обратите внимание, что JSON :: Any может быть принудительно (через среду или путем передачи соответствующих параметров import()), чтобы выбрать конкретный сервер. Так работает тестовый набор, и он документирован.

+2

MooseX :: Хранение - единственный правильный ответ. – jrockway

+0

@jrockway Вы можете использовать процедуры десериализации из KiokuDB или написать свой собственный ... но так как MooseX :: Storage на данный момент три или четыре года и хорошо протестированы в * много * производственных средах, это не большие решения. – perigrin