[Linux-aus] Moose, JSON Question
David Lloyd
lloy0076 at adam.com.au
Sun Jan 4 11:13:59 EST 2009
Daniel,
On 03/01/2009, at 7:49 PM, Daniel Pittman wrote:
> David Lloyd <lloy0076 at adam.com.au> writes:
>
>> At the recent OSDC I heard about Moose so I thought I'd take the
>> Moose
>> out on the hunting range to see what I could come up with.
>
> Your question isn't actually Moose related, but a generic Perl
> question,
> as far as I can tell.
>
That's what I thought but seeing I'd put in a module I don't have that
much experience with, and one that probably fiddles a bit to do what
it does I'd mentin it.
>> Now, I also wanted to fiddle a bit with JSON so I thought, well,
>> let's
>> do some TDD as practice and see what happens. Here's a cut down
>> version of TestJSON.pm:
>
> [...]
>
>> sub json2perl {
>> my ($self, $perl) = @_;
>> return from_json($perl);
>> }
>
> This will call from_json with only one argument, the '$perl' value.
And by the way, it works.
>> It appears that "from_json" is being interpreted as an object
>> method and then
>> dispatched to JSON::from_json like this:
>>
>> JSON::from_jason($object_hash, $json);
>
> Yes, it is — because you explicitly called it that way. The '->'
> operator passes the object on the left to the function on the right as
> the first argument.
>
> This has nothing to do with Moose, and would work the same way in any
> object / package you created.
Aye.
>
>> Take careful note that the object hash is now in the array. The
>> function then reads the very first argument passed to it and then
>> balks.
>>
>> In another session I managed this:
>>
>> DB<3> $tj->to_json({a => 'b'});
>> Can't locate object method "a" via package "JSON" at /Library/
>> Perl/5.8.8/JSON.pm
>> line 136.
>
> The JSON package to_json treats the hash keys in the second argument
> as
> local method calls, resulting in this error.
Ah, well spotted, I didn't quite see that.
>> So, a few questions:
>>
>> 1. If one uses a module in Perl 5.8.10 inside an object, but more
>> specifically a Moose based object, and it imports functions into
>> the module's namespace, it appears that the functions really are
>> in the namespace and can be called
>
> Correct.
>
>> 1. But the caveat is that they don't do what you expect them to
>> do...
>
> They don't do what *you* expect them to do — your examples did exactly
> what I expected. ;) More seriously, this is the standard Perl
> behaviour, not anything to do with Moose or otherwise.
Sometimes Perl gives me the willies, to use the vernacular.
>> 2. Interestingly if I remove the perl2json or json2perl class, the
>> class methods
>> "to_json" and "from_json" respectively (or both) throw a "can't
>> be found in
>> namespace error", i.e. Moose/Perl can't find them
>> 1. Which implies they're being loaded because they're used in
>> the module...
>> 2. I've looked into JSON's source code and it seems to be doing
>> some funky stuff
>> to figure out which backend JSON:: one is using but other
>> than that it looks
>> like a standard Exporter to me, it just has rolled its own
>> export and import
>> functions
>
> They should show up in the namespace... and a quick test here shows
> that
> they do:
>
> perl -e 'package Test; use JSON; package main; \
> print UNIVERSAL::can("Test", "to_json") ? "imported\n" :
> "missing\n"'
I must have missed that when I did:
perl -Ilib -MTestJSOn -e -d 0
...
DB<?> S
[lots of methods]
...
>
>> 3. As a matter of OO style, is it "nice" to expose "used" package's
>> imports in the class one is making even though the behaviour if
>> you use them as a class method appears to be strange
>
> Generally, no, you wouldn't expect to import a random class into your
> object and have it add methods.
Exactly - I think my trotting about in Java lately has kind of
insulated me a little .
> With Moose this is even less common: the 'Role' type is used for the
> purpose of class extension, in a cleaner fashion than random exports
> into your namespace.
*hmm*
A "JSON" role?
>> 1. That is, in this case I did "use JSON;" and caused "from_json"
>> and "to_json" to materialise - if I have an actual object
>> (TestJSON->new()) I can call them but as shown the behaviour
>> is suboptimal
>
> Your calling convention is wrong: the JSON methods need to have their
> data as the first argument, and calling them as methods means that
> they
> don't.
I understood that much - hopefully my commentary indicated that I'd
detected that they were being called as class methods rather than
POPMs (Plain Old Perl Methods).
> The summary is, don't do that. Use your wrapper methods. ;)
I was kind of hoping that Moose or the Perl Object system would
insulate me from this type of shenanigans. For example:
package myclass;
import some.random.letus.ExplodeTheWorld;
public class myclass {
public myclass ();
}
...that I couldn't do:
public myclass;
public class evil {
public static void main(int arg, string argv[]) {
evil.ExplodeTheWorld();
}
}
...whereas it seems that in Perl I could.
DSL
More information about the linux-aus
mailing list