Re: Fwd: Fwd: Re: What's the best approach for translating an attribute upon creation?
Thanks for that bit. I changed my code so that I am calling a method from my BUILDARGS sub. This seems to be working quite nicely. Steve On 2/26/2010 2:30 PM, Jesse Luehrs wrote: On Fri, Feb 26, 2010 at 12:52:44PM -0500, Steve wrote: I've moved on to a slightly more complex situation. The same phone call record contains two different date fields. One is a string like 'Jan 21, 2010' (incidentally, this date is repeated for each record, as it represents the end of the billing cycle), which I have successfully converted with: type 'My::Types::Date' => as 'Str' => where { defined $_ and $_ =~ /^\d{8}$/ }; coerce 'My::Types::Date' => from 'Str' => via { my $d = shift; if ($d =~ /^([a-zA-Z]+) ([0-9]+).*(\d\d\d\d)$/) { ...this code works} The second situation is complex. Instead of a full date with year, month, and day of the call, I am given MM/DD. No year. I have logic that 'figures out' the year based on the billing cycle end date (above) which I put into&explodeDate. Being a big fan of perl's debugger, I've identified that by the time the subroutine gets called, I have no reference to either the date, or my object. elsif ($d =~ \d\d\/\d\d) {$d =&explodeDate;} sub explodeDate { my $self = shift; # Nothing here... } Well, you're calling explodeDate as a function, not as a method. Try $self->explodeDate (or more probably, $self->explodeDate($d), since you seem to be expecting it to get the date also). Also, you shouldn't use a leading& to call regular functions, even when you're not trying to call them as methods... it's equivalent in this case, but can cause issues in other cases (particularly with functions with prototypes). Is this proper use of coercion, or is there a better way? If I'm on the right track, how do I get access to my object within 'explodeDate'? -doy No virus found in this incoming message. Checked by AVG - www.avg.com Version: 9.0.733 / Virus Database: 271.1.1/2711 - Release Date: 02/26/10 02:34:00
Re: Fwd: Fwd: Re: What's the best approach for translating an attribute upon creation?
On Fri, Feb 26, 2010 at 12:52:44PM -0500, Steve wrote: > I've moved on to a slightly more complex situation. The same phone call > record contains two different date fields. One is a string like 'Jan > 21, 2010' (incidentally, this date is repeated for each record, as it > represents the end of the billing cycle), which I have successfully > converted with: > > type 'My::Types::Date' => as 'Str' => where { defined $_ and $_ =~ > /^\d{8}$/ }; > coerce 'My::Types::Date' => from 'Str' => via { my $d = shift; > if ($d =~ /^([a-zA-Z]+) ([0-9]+).*(\d\d\d\d)$/) { ...this code works} > > The second situation is complex. Instead of a full date with year, > month, and day of the call, I am given MM/DD. No year. I have logic > that 'figures out' the year based on the billing cycle end date (above) > which I put into &explodeDate. Being a big fan of perl's debugger, I've > identified that by the time the subroutine gets called, I have no > reference to either the date, or my object. > > elsif ($d =~ \d\d\/\d\d) {$d = &explodeDate;} > > sub explodeDate { > my $self = shift; # Nothing here... > } Well, you're calling explodeDate as a function, not as a method. Try $self->explodeDate (or more probably, $self->explodeDate($d), since you seem to be expecting it to get the date also). Also, you shouldn't use a leading & to call regular functions, even when you're not trying to call them as methods... it's equivalent in this case, but can cause issues in other cases (particularly with functions with prototypes). > Is this proper use of coercion, or is there a better way? If I'm on the > right track, how do I get access to my object within 'explodeDate'? -doy
Fwd: Fwd: Re: What's the best approach for translating an attribute upon creation?
I've moved on to a slightly more complex situation. The same phone call record contains two different date fields. One is a string like 'Jan 21, 2010' (incidentally, this date is repeated for each record, as it represents the end of the billing cycle), which I have successfully converted with: type 'My::Types::Date' => as 'Str' => where { defined $_ and $_ =~ /^\d{8}$/ }; coerce 'My::Types::Date' => from 'Str' => via { my $d = shift; if ($d =~ /^([a-zA-Z]+) ([0-9]+).*(\d\d\d\d)$/) { ...this code works} The second situation is complex. Instead of a full date with year, month, and day of the call, I am given MM/DD. No year. I have logic that 'figures out' the year based on the billing cycle end date (above) which I put into &explodeDate. Being a big fan of perl's debugger, I've identified that by the time the subroutine gets called, I have no reference to either the date, or my object. elsif ($d =~ \d\d\/\d\d) {$d = &explodeDate;} sub explodeDate { my $self = shift; # Nothing here... } Is this proper use of coercion, or is there a better way? If I'm on the right track, how do I get access to my object within 'explodeDate'? Steve This method works great! I was very close to getting coercion to work, but somehow my substitution returned '2' every time. Thanks all for the help Steve Something along the lines of the following should work: package Types; use Moose::Util::TypeConstraints; # note, need a type here, as otherwise coersions won't work if done as a subtype of 'Str' type "Types.pcr" => where { defined $_ and $_ =~ /^\d+$/ }; coerce "Types.pcr" => from "Str" => via { my $v = shift; $v =~ s/-//g; $v }; package UsageDetail; use Moose; # Note the 'coerce' flag and isa here has pcr => ( is => "rw", isa => "Types.pcr", coerce => 1 ); package main; my $dashful = UsageDetail->new( pcr => "9-8-7-6-5-4-3-2-1" ); my $dashless = UsageDetail->new( pcr => "123456789" ); print "Dashful: " . $dashful->pcr . "\n"; print "Dashless: " .$dashless->pcr . "\n" - The above gives: Dashful: 987654321 Dashless: 123456789 On Fri, Feb 26, 2010 at 2:21 PM, Steve wrote: I have been attempting to solve the following problem: I have a class, 'UsageDetail' which takes a CSV phone call record and inserts it into my database. One of the attributes, 'WirelessNumber' has dashes in it, ie: '989-555-1212'. I don't want to store the dashes in the db. I've rtfm over and over, but I haven't been successful in storing without the dashes. I've tried subtypes, but that didn't work. BTW, the values passed in to my constructor are not ONLY the 3-3-4 digit format, sometimes the wireless number is 2 digits, and my WirelessNumber attr. isa 'Str' currently. Also, I can't modify the value passed into my constructor, as it is used for many different tables. Any suggestions are greatly appreciated. Steve No virus found in this incoming message. Checked by AVG - www.avg.com Version: 9.0.733 / Virus Database: 271.1.1/2711 - Release Date: 02/26/10 02:34:00 No virus found in this incoming message. Checked by AVG - www.avg.com Version: 9.0.733 / Virus Database: 271.1.1/2711 - Release Date: 02/26/10 02:34:00