An Easy Way

There are a few simple ways of doing it. You could just have a method that calls the attributes that you want to search, something like this:

sub search_me { my $self = shift; my ($search) = @_; my @results = (); foreach my $attr ( qw/title message author/ ) { if ( $self->$attr() =~ m/$search/ ) { push(@results, { 'name' => $attr, 'value' => $self->$attr() } +); } } return @results; }

Which would return something like:

$VAR1 = [ { 'name' => 'title', 'value' => 'My title xyzzy' } ];

But that's no fun! You'd have to change that method every time you changed your Note class. Plus, this is an excellent chance to do something amusing with Moose attributes! What if you could just mark an attribute as searchable, then have a method that goes through and searches those attributes?

A Harder Way

Well, you could define a 'Searchable' trait, like so:

package Note::Attribute::Trait::Searchable { use Moose::Role; Moose::Util::meta_attribute_alias('Searchable'); }

Then have a role that uses that trait to search through your attributes, like so:

package Note::Searchable { use Moose::Role; sub search { my $self = shift; my ($search_string) = @_; my $meta = $self->meta; my @results; # Go through all attributes on your object foreach my $attribute ( map { $meta->get_attribute($_) } sort $meta->get_attribute_list ) { # Skip attributes unless they're specifically searchable unless ( $attribute->does('Note::Attribute::Trait::Searcha +ble') ) { next; } my $reader = $attribute->get_read_method(); my $value = $self->$reader; if ( $value =~ m/$search_string/ ) { push( @results, { 'name' => $attribute->name, 'value' => $value } +); } } return @results; } }

Then finally, in your class, you mark the traits you want as searchable:

package Note { use Moose; with 'Note::Searchable'; # We want to search title, message, and author has 'title' => ( is => 'rw', isa => 'Str', traits => [qw/Searcha +ble/] ); has 'message' => ( is => 'rw', isa => 'Str', traits => [qw/Searcha +ble/] ); has 'author' => ( is => 'rw', isa => 'Str', traits => [qw/Searcha +ble/] ); # We don't want to search "other" has 'other' => ( is => 'rw', isa => 'Str' ); no Moose; }

Then this code returns the same result:

my $note = Note->new( title => 'My title xyzzy', message => 'My message', author => 'me' ); use Data::Dumper; say Dumper [ $note->search('xyzzy') ];
...returns...
$VAR1 = [ { 'name' => 'title', 'value' => 'My title xyzzy' } ];

There's a lot more up-front work, and it's probably overkill for what you want to do. Still, now you can add and delete new attributes as you please, and they'll be searched properly so long as they're marked searchable!

stephen


In reply to Re: search for similiar text in Moose Attributes by stephen
in thread search for similiar text in Moose Attributes by demonking

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.