如何将Moose对象转换为JSON以在Catalyst中使用?

时间:2010-08-02 21:34:32

标签: perl json serialization moose catalyst

我有一系列Moose对象,我希望通过JSON::XS提供给Catalyst::View::JSON。 JSON :: XS无法编码有福的数据结构。我知道有MooseX::Storage::Format::JSON可以 - 有点 - 做我想做的事;但是,它似乎相当沉重。我正在寻找的内容与XXX.pm提供的信息基本相同。我只是希望递归地使原始数据结构不复见,因此JSON::XSJSON::Any内部使用的C:V:JSON的驱动程序)可以显示它。

Catalyst::View::JSONJSON::XSMoose个对象一起使用的最佳方法是什么?看来我有四个明显的选择:

  1. Catalyst::View::JSON与Moose对象一起工作,修补C:V:JSON以从freeze读取,并在暴露的参数是Moose对象时完成请求。
  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(如果{{1},则不要想到错误。为调用JSON::Any的Moose对象选择不同的内部编码器。
  3. 弄清楚如何递归取消,让JSON::XS做它的事情。
  4. 根本不要使用Catalyst::View::JSON。只需写入STDOUT Catalyst::View::JSON并手动完成请求..这似乎是最讨厌的。
  5. 我确定还有其他一些选择,任何想法?什么是我最好的选择?

3 个答案:

答案 0 :(得分:5)

我倾向于使用MooseX :: Storage来提供选项3来提供一个pack()方法,该方法返回一个Perl数据结构,我可以在我的存储中填充这些结构,以便View可以根据它的选择进行渲染。

另请注意,可以强制JSON :: Any(通过环境,或通过将适当的参数传递给import())来选择特定的后端。这就是测试套件的工作方式,并记录在案。

答案 1 :(得分:4)

如果您不关心完全取消对象并使其完全无法使用(从Moose的角度来看),请尝试从Data::Structure::Util取消。

我个人更喜欢MooseX::Storage以获得更优雅和可持续的解决方案。

答案 2 :(得分:0)

喜欢它还是讨厌它我的最终解决方案是恢复到现在已弃用的JSON::Syck,这正是我想要的。这是一个快速的非Moose逻辑非Moose序列化到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甚至不能代表所有的perl   数据结构是非对象。

     

...

     

你的问题是:为什么我不能   将此1MB jpeg图像作为ascii文件发送    - 只是因为ascii不能代表八位字节。

     

...

     

或许你只是想扔掉   一些垃圾,并期待JSON :: XS   做对你有益的事(但错了   对于其他人) - 根本没有   JSON :: XS的神奇猜测方式   想要什么。

     

...

     

TO_JSON就是这样。别的什么都是   狂野的猜测。

     

...

     

那么也许你应该尝试那些东西   JSON实际上可以代表。投掷   一些对象层次结构,希望如此   它会做“正确的事”   显然糟糕的软件工程 - 试试   当你的protocl时,不要去攻击黑客   需要JSON,然后发送JSON,不需要   期待json图书馆修复你的   首先是无效的消息。

我不知道如何回应,除了我不关心。只是工作!喜欢:: SYCK 。我不希望对象完美地转换为JSON。但是,我认为我只是希望它能够发挥作用的80%。我正在使用JSON进行jQuery导入,在脑部手术期间不执行银行交易。最终,我不想使用特殊的角色......我希望发送给它的任何内容都可以神奇地转换为一个级别,使其在响应jQuery JSON请求时非常有用。

更新

对不起,我错过了这些回复,直到有人说我在一个不相关的媒体中拖钓。 MooseX :: Storage不适用于非Moose类,我想要一种通用的方式来表示JSON格式的存储。不幸的是,这些藏匿的一些成员是Moose物体。 XML :: Simple可以做到这一点,Data::Dumper可以做到这一点,JSON :: Syck可以做到这一点,列表继续 - 我只是想完成它。它与Perl不一定是1:1,说实话我希望它完全接近JSON::Syck默认的方式。我在这里的观点是,“我如何使JSON::XS完全像JSON::Syck目前的工作”?而且,你的答案是你做不到的。所以我没有采用不同的解决方案。编写代码需要花钱,如果Syck已经做得正确,为什么我要写to_JSON ...我想说的是负担是在nay-sayers上显示什么是Syck序列化的时尚不太可取。另外,请记住JSON::SyckAudry播种,他绝不是巨魔,白痴或“大脑受损”;或者,我正在抛出的任何其他术语。我将以此结束:缺少JSON::Syck的错误序列化路由以及已经正在工作的所需输出使我相信这对我来说是一个不错的选择。而且,MooseX :: *:JSON可以与任意Moose对象做不同的事情吗?为什么你认为不能编写代码来接受Moose对象而不是它上面的方法?如果您不这么认为,请回答一些实质内容 - 我希望看到更好的回应。谢谢。 (针对@jrockway和@Ether)