Class::Struct comparison & MOP
1 How do I compare Class::Struct instances (objects)
for equality (or precedence)?
E.g.,
use Class::Struct MyStruct =>
[foo => '$',
bar => '$',
baz => '$'];
my MyStruct $a = MyStruct->new(foo => "a");
my MyStruct $b = MyStruct->new(bar => "b");
my MyStruct $a1 = MyStruct->new(foo => "a");
Both ($a eq $a1) and ($a eq $b) return false which is wrong for the
first expression.
I can write my own comparison, of course:
sub struct_eq ($$) {
my ($x,$y) = [at] _;
List::AllUtils::notall
(sub { $_ }, (List::AllUtils::pairwise
(sub { $a eq $b }, [at] $x, [at] $y)));
}
but this does simple version does not work because some fields are
undefined and I have to check than and it quickly becomes a nightmare.
I could write a tedious function like
sub MyStruct_eq ($$) {
my ($x,$y) = [at] _;
(defined $x->foo and defined $y->foo and $x->foo eq $y->foo)
or (not defined $x->foo and not defined $y->foo)
.....
}
but there must be a better way.
2. Is there a way to get a list of all fields in a struct?
Class::Fields seems to claim to be able to do it, but I cannot figure
out how to use it.
Class::Fields->show_fields('MyStruct') returns nothing.
MyStruct->show_fields is not defined.
I am lost.
I would also like to be able to access MyStruct instance fields by name.
I know I can do that using hash{} instead of array[] in the definition,
but I would like to preserve the underlying array structure for passing
to Text::CSV functions (I guess I could use "values" for that too).
E.g., I want to be able to write something like
my $mystruct_foo_pos = MyStruct->getpos('foo');
and have $mystruct_foo_pos set to 0.
then I will be able to write
my MyStruct $a = MyStruct->new(...);
$a[$mystruct_foo_pos] = "a";
Thanks!
--
Sam Steingold (http://sds.podval.org/) on CentOS release 5.3 (Final) X
http://iris.org.il http://pmw.org.il http://memri.org http://ffii.org
http://dhimmi.com http://palestinefacts.org http://jihadwatch.org
My other CAR is a CDR.
--
To unsubscribe, e-mail: beginners-unsubscribe [at] perl.org
For additional commands, e-mail: beginners-help [at] perl.org
http://learn.perl.org/
Re: Class::Struct comparison & MOP
Hi Sam,
welcome aboard.
On Friday 04 Mar 2011 18:47:40 Sam Steingold wrote:
> 1 How do I compare Class::Struct instances (objects)
> for equality (or precedence)?
>
> E.g.,
>
> use Class::Struct MyStruct =>
> [foo => '$',
> bar => '$',
> baz => '$'];
>
> my MyStruct $a = MyStruct->new(foo => "a");
> my MyStruct $b = MyStruct->new(bar => "b");
> my MyStruct $a1 = MyStruct->new(foo => "a");
>
First of all I should note that there are better accessor generators already
than Class::Struct. see:
http://www.shlomifish.org/lecture/Perl/Newbies/lecture5/acce ssors/
where I recommend either Class-Accessor (simple, sane and popular), Class-
XSAccessor (very fast) or Moose (extremely powerful and versatile, but has a
small compile-time overhead). Class::Struct should also be OK.
To answer your question you can use the or operator for this:
http://www.shlomifish.org/lecture/Perl/Newbies/lecture4/and_ or/sort.html
Moreover, don't call your lexical variables "$a" and "$b" because they are
used in sort.
> Both ($a eq $a1) and ($a eq $b) return false which is wrong for the
> first expression.
> I can write my own comparison, of course:
>
> sub struct_eq ($$) {
> my ($x,$y) = [at] _;
> List::AllUtils::notall
> (sub { $_ }, (List::AllUtils::pairwise
> (sub { $a eq $b }, [at] $x, [at] $y)));
> }
>
> but this does simple version does not work because some fields are
> undefined and I have to check than and it quickly becomes a nightmare.
> I could write a tedious function like
>
> sub MyStruct_eq ($$) {
> my ($x,$y) = [at] _;
> (defined $x->foo and defined $y->foo and $x->foo eq $y->foo)
> or (not defined $x->foo and not defined $y->foo)
> .....
> }
>
> but there must be a better way.
>
> 2. Is there a way to get a list of all fields in a struct?
> Class::Fields seems to claim to be able to do it, but I cannot figure
> out how to use it.
> Class::Fields->show_fields('MyStruct') returns nothing.
> MyStruct->show_fields is not defined.
> I am lost.
>
> I would also like to be able to access MyStruct instance fields by name.
> I know I can do that using hash{} instead of array[] in the definition,
> but I would like to preserve the underlying array structure for passing
> to Text::CSV functions (I guess I could use "values" for that too).
> E.g., I want to be able to write something like
>
> my $mystruct_foo_pos = MyStruct->getpos('foo');
>
> and have $mystruct_foo_pos set to 0.
> then I will be able to write
>
> my MyStruct $a = MyStruct->new(...);
>
> $a[$mystruct_foo_pos] = "a";
>
You can do it with Moose or friends ( http://www.iinteractive.com/moose/ )
using intropsection. And you should not use arrays references for structs, but
hash references, where it is a bit easier.
Regards,
Shlomi Fish
--
------------------------------------------------------------ -----
Shlomi Fish http://www.shlomifish.org/
The Case for File Swapping - http://shlom.in/file-swap
There is no IGLU Cabal! Home-made Cabals eventually superceded the power and
influence of the original IGLU Cabal, which was considered a cutting edge
development at its time.
Please reply to list if it's a mailing list post - http://shlom.in/reply .
--
To unsubscribe, e-mail: beginners-unsubscribe [at] perl.org
For additional commands, e-mail: beginners-help [at] perl.org
http://learn.perl.org/
Re: Class::Struct comparison & MOP
Hi Shlomi,
Thanks for your kind reply.
> * Shlomi Fish <fuybzvs [at] vtyh.bet.vy> [2011-03-04 20:37:51 +0200]:
> On Friday 04 Mar 2011 18:47:40 Sam Steingold wrote:
>> 1 How do I compare Class::Struct instances (objects)
>> for equality (or precedence)?
>>
>> E.g.,
>>
>> use Class::Struct MyStruct =>
>> [foo => '$',
>> bar => '$',
>> baz => '$'];
>>
>> my MyStruct $a = MyStruct->new(foo => "a");
>> my MyStruct $b = MyStruct->new(bar => "b");
>> my MyStruct $a1 = MyStruct->new(foo => "a");
>>
>
> First of all I should note that there are better accessor generators already
> than Class::Struct. see:
>
> http://www.shlomifish.org/lecture/Perl/Newbies/lecture5/acce ssors/
>
> where I recommend either Class-Accessor (simple, sane and popular), Class-
> XSAccessor (very fast) or Moose (extremely powerful and versatile, but has a
> small compile-time overhead). Class::Struct should also be OK.
I cannot figure out how to use Class::Accessor.
what are the specific lines of code equivalent to my code above?
>> Both ($a eq $a1) and ($a eq $b) return false which is wrong for the
>> first expression.
>> I can write my own comparison, of course:
>>
>> sub struct_eq ($$) {
>> my ($x,$y) = [at] _;
>> List::AllUtils::notall
>> (sub { $_ }, (List::AllUtils::pairwise
>> (sub { $a eq $b }, [at] $x, [at] $y)));
>> }
>>
>> but this does simple version does not work because some fields are
>> undefined and I have to check than and it quickly becomes a nightmare.
>> I could write a tedious function like
>>
>> sub MyStruct_eq ($$) {
>> my ($x,$y) = [at] _;
>> (defined $x->foo and defined $y->foo and $x->foo eq $y->foo)
>> or (not defined $x->foo and not defined $y->foo)
>> .....
>> }
>>
>> but there must be a better way.
>>
>> 2. Is there a way to get a list of all fields in a struct?
>> Class::Fields seems to claim to be able to do it, but I cannot figure
>> out how to use it.
>> Class::Fields->show_fields('MyStruct') returns nothing.
>> MyStruct->show_fields is not defined.
>> I am lost.
>>
>> I would also like to be able to access MyStruct instance fields by name.
>> I know I can do that using hash{} instead of array[] in the definition,
>> but I would like to preserve the underlying array structure for passing
>> to Text::CSV functions (I guess I could use "values" for that too).
>> E.g., I want to be able to write something like
>>
>> my $mystruct_foo_pos = MyStruct->getpos('foo');
>>
>> and have $mystruct_foo_pos set to 0.
>> then I will be able to write
>>
>> my MyStruct $a = MyStruct->new(...);
>>
>> $a[$mystruct_foo_pos] = "a";
>>
>
> You can do it with Moose or friends ( http://www.iinteractive.com/moose/ )
> using intropsection.
Moose is far too heavy-weight for my purposes.
> And you should not use arrays references for structs, but
> hash references, where it is a bit easier.
As I said, I need to pass it to CSV writer, so it must be an array.
So, the gist of your answer is that my problems have no solution:
- I cannot compare for equality of order objects created with the
Class::Struct->new constructor
- I cannot get the list of fields of the structure created by
Class::Struct.
Right?
--
Sam Steingold (http://sds.podval.org/) on CentOS release 5.3 (Final) X
http://www.memritv.org http://iris.org.il http://thereligionofpeace.com
http://memri.org http://honestreporting.com http://truepeace.org
Lisp: it's here to save your butt.
--
To unsubscribe, e-mail: beginners-unsubscribe [at] perl.org
For additional commands, e-mail: beginners-help [at] perl.org
http://learn.perl.org/