revdiablo's Journal revdiablo's use Perl Journal en-us use Perl; is Copyright 1998-2006, Chris Nandor. Stories, comments, journals, and other submissions posted on use Perl; are Copyright their respective owners. 2012-01-25T02:46:52+00:00 pudge Technology hourly 1 1970-01-01T00:00+00:00 revdiablo's Journal Anonymous objects as easily as hashrefs? <p>Is there anything buried in the sea of Moose--or any object system on CPAN--that allows creating anonymous objects about as easily as creating anonymous hashrefs? I would be much happier using tiny objects to store structured data in my code, but the hashref syntax is just so darn convenient.</p><p>Here's an example of what I'd love to be able to do:</p><blockquote><div><p> <tt>while (my $line = readline()) {<br>&nbsp; &nbsp; my ($ding, $dong) = parse($line);<br> <br>&nbsp; &nbsp; next if $seen{$ding}++;<br> <br>&nbsp; &nbsp; push @dingfirsts, Object::Anonymous-&gt;new(<br>&nbsp; &nbsp; &nbsp; &nbsp; ding =&gt; $ding,<br>&nbsp; &nbsp; &nbsp; &nbsp; dong =&gt; $dong,<br>&nbsp; &nbsp; &nbsp; &nbsp; line =&gt; $.,<br>&nbsp; &nbsp; );<br>}<br> <br>for (@dingfirsts) {<br>&nbsp; &nbsp; say "First ", $_-&gt;ding, " on line ", $_-&gt;line;<br>}</tt></p></div> </blockquote><p>Please ignore the obvious flaws in this contrived example. The most important part, to me, is that the object is defined by its constructor, and nowhere else. Methods would get created for any attributes given in the constructor.</p><p>Here's a quick implementation that may help explain what I'm after. There are some really obvious flaws that would prevent me from ever actually using this code--most significantly, it's modifying the Anonyject class at runtime, so it really isn't anonymous at all--but the mechanics are pretty close to what I'd want.</p><blockquote><div><p> <tt>package Anonyject;<br> <br>sub new {<br>&nbsp; &nbsp; my $name = shift;<br>&nbsp; &nbsp; my %args = @_;<br>&nbsp; &nbsp; my $self = {};<br> <br>&nbsp; &nbsp; for my $arg (keys %args) {<br>&nbsp; &nbsp; &nbsp; &nbsp; # Store the given value<br>&nbsp; &nbsp; &nbsp; &nbsp; $self-&gt;{$arg} = $args{$arg};<br> <br>&nbsp; &nbsp; &nbsp; &nbsp; # Create the accessor<br>&nbsp; &nbsp; &nbsp; &nbsp; my $methname = __PACKAGE__ . "::" . $arg;<br>&nbsp; &nbsp; &nbsp; &nbsp; *{$methname} = sub {<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; my ($innerself) = @_;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return $innerself-&gt;{$arg};<br>&nbsp; &nbsp; &nbsp; &nbsp; };<br>&nbsp; &nbsp; }<br> <br>&nbsp; &nbsp; bless $self, $name;<br>}<br> <br>package main;<br>use feature 'say';<br> <br>my $obj1 = Anonyject-&gt;new(<br>&nbsp; &nbsp; ding =&gt; "wing",<br>&nbsp; &nbsp; dong =&gt; "wong",<br>&nbsp; &nbsp; line =&gt; 23_939,<br>);<br>my $obj2 = Anonyject-&gt;new(<br>&nbsp; &nbsp; something =&gt; "else",<br>);<br> <br>say $obj1-&gt;ding;&nbsp; &nbsp; &nbsp; # Says "wing"<br>say $obj2-&gt;something; # Says "else"<br> <br>say $obj1-&gt;something; # Should break, but doesn't<br>say $obj1-&gt;broken;&nbsp; &nbsp; # Breaks properly</tt></p></div> </blockquote><p>So that's wishful thinking of the day. I'm hoping one of the popular object systems already does what I want, but maybe I can use Class::MOP to implement this properly. Any ideas would be lovely.</p> revdiablo 2009-09-15T22:44:15+00:00 journal