•Re: Object::MultiType - Perl Objects as Hash, Array & Scalar in the same time!
by merlyn (Sage) on May 10, 2003 at 11:15 UTC
|
I guess the big problem for me here is "why?". What problem does this solve? Or are you doing it just because you can?
In all the Perl programming I've done, I've never found myself saying "gee, I wish this thing could act like a scalar, array, and a hash!". And I've done a lot of Perl programming, even a lot of unusual programming for my column articles and lecture examples.
-- Randal L. Schwartz, Perl hacker
Be sure to read my standard disclaimer if this is a reply. | [reply] |
|
|
Why?
Is not because I can, is because I need. ;-P
Is for a XML module that need to work in the same time in different ways. For example, in XML::Simple you have a hash tree, where inside it you have some parts that are ARRAY ref, soo you need to know when you have an ARRAY and a HASH to access the data, or you need to configure the parser to force the ARRAY to always have an ARRAY on unique points.
With my idea you can just work directly with the HASH or ARRAY to get the data, make a search, etc... All using the basic Perl syntax for HASH, ARRAY, CODE & SCALAR.
Here's an example of how you can access the data:
my $addr = $xml->{config}{server}->('name','=~','sahara')->{address}
+[0] ;
## the same, it just get the first:
my $addr = $xml->{config}{server}->('name','=~','sahara')->{address}
+ ;
## return all the addresses:
my @addrs = $xml->{config}{server}->('name','=~','sahara')->{address
+} ;
## Get the first server node:
my $server = $xml->{config}{server}[0] ;
## or without [0], since wihtout always return the 1st:
my $server = $xml->{config}{server} ;
## Or get the server that have a specific name,
## when you don't know the order:
my $server = $xml->{config}{server}->('name','eq','sahara') ;
my $addr = $server->{address} ;
## Print the content:
print "Server content: $server\n" ;
__DATA__
<config logdir="/var/log/foo/" debugfile="/tmp/foo.debug">
<server name="sahara" osname="solaris" osversion="2.6">
<address>10.0.0.101</address>
<address>10.0.1.101</address>
</server>
<server name="gobi" osname="irix" osversion="6.5">
<address>10.0.0.102</address>
</server>
<server name="kalahari" osname="linux" osversion="2.0.34">
<address>10.0.0.103</address>
<address>10.0.1.103</address>
</server>
</config>
Note that this styles to get the data are still in plan stage. I'm just finishing the Object::MultiType module to see all the resources that I have to do that... But the styles above are already supported! ;-P
Graciliano M. P.
"The creativity is the expression of the liberty". | [reply] [d/l] |
Re: Object::MultiType - Perl Objects as Hash, Array & Scalar in the same time!
by diotalevi (Canon) on May 12, 2003 at 07:24 UTC
|
It turns out that when you dumped Symbol::genref you picked up exactly the bug I was attempting to avoid. You must delete the hash entry from the symbol table you just referenced. Do that and your code would look identical to Symbol::genref. bart noticed that genref() (or the equivalent code (yours)) is actually very slow. PodMaster egged me on and I ended up creating Lexical::Typeglob::lexglob which is really just like Symbol::genref except it really avoids mucking with the symbol table. Its also four times faster than Symbol::genref which is nice. For the moment it can be downloaded from my personal site at http://www.greentechnologist.org/downloads/perl/Lexical-Typeglob-0.01.tar.gz and I'm considering publishing it on CPAN. I can't do that just yet because its missing documentation and a better test suite.
| [reply] [d/l] [select] |
|
|
Many thanks for all the work to test GLOB through Symbol. But now I'm fully avoiding GLOB and Symbol::.
I have created a Saver object inside Object::MultiType::Saver, where this object stay inside the MultiType object, and now there is no need of GLOB or any extra thing.
Thanks (to you and PodMaster) for the previous advices to avoid GLOB! ;-P
Graciliano M. P.
"The creativity is the expression of the liberty".
| [reply] |
|
|
sub new {
my $class = shift ;
local(*NULL);
my $this = {
s => \'' ,
a => [] ,
h => [] ,
c => sub{} ,
g => \*NULL ,
} ;
bless($this,$class);
return( $this ) ;
}
| [reply] [d/l] [select] |
|
|
Re: Object::MultiType - Perl Objects as Hash, Array & Scalar in the same time!
by diotalevi (Canon) on May 10, 2003 at 05:31 UTC
|
I dislike this whole idea because everything here is ultimately a global and subject to the global garbage collecting rules. I can see this being a serious issue for object oriented systems where it matters in which order object destruction occurs. PodMaster suggested in the other node that its possible to remove the global component from one of Symbol's gensym globs and I think that once that exists, this module can work. Until then... ick. Double ick.
| [reply] |
|
|
I don't use Symbol::gensym anymore! Please, test and take a look in the module.
I still use GLOB, where it's cleanned with the object! Note that in Perl much things in your objects are GLOBAL, or have external access. (For example, when you use a IO::Handle, and any module that use it, like IO::File, you have a global GLOB object).
But any global thing in OO is wrong, I know. But for now is that, with GLOB! Looking for better ways...
Graciliano M. P.
"The creativity is the expression of the liberty".
| [reply] |
|
|
| [reply] |
|
|
Eh - I just created Lexical::Typeglob. For the moment it exists on my web site at http://www.greentechnologist.org/downloads/perl/ and it'll go on CPAN soon-ish.
Added: You know what? I'm a moron - Symbol already does this and the whole reaping issue is moot.
| [reply] |
|
|
|
|
Re: Object::MultiType - Perl Objects as Hash, Array & Scalar in the same time!
by midibach (Acolyte) on Feb 21, 2005 at 17:25 UTC
|
Wanted to add my $.02:
So far, I have a love it / hate it relationship with this module. I started using XML::Smart after getting sick of having to worry about what is an array and what is a scalar inside an XML originated data structure. Works well, so I went ahead and decided to put Object::MultiType to use on cgi form variables as well. I like the old cgi-lib way of getting everything into a hash, but that creates issues with multi-valued parameters. So now I have a scalar, array, and hash (keys for Boolean) of all cgi posted data as well.
So far so good.
The hate it part of this relationship is the obvious. Some modules don’t like getting fed multi-typed data so you have to export the tree. This takes you back to square one. I also like to employ the following:
no strict "refs";
&$command($data);
use strict;
And that is a no-go with multi-type data, you have to use the (‘$’) function to get the real scalar out first. Also, Data::Dumper becomes a mess; you really need to export the tree first.
All in all however, I’m sticking with my multi-typed data for now. The only module I was using that didn’t like the multi-typed data is XML::Simple and that is replaced with XML::Smart now. I’m also finding that, for me at least, the worries that Object::MultiType bring are good ones. Being that I am reminded where my data is originating as apposed to being hung up on data structure semantics. And this is the type of consistency that I rather be concerned with. | [reply] [d/l] |