Skip Menu |

Preferred bug tracker

Please visit the preferred bug tracker to report your issue.

This queue is for tickets about the DBIx-Class-InflateColumn-Boolean CPAN distribution.

Report information
The Basics
Id: 100827
Status: resolved
Priority: 0/
Queue: DBIx-Class-InflateColumn-Boolean

People
Owner: GRAF [...] cpan.org
Requestors: haarg [...] haarg.org
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: (no value)
Fixed in: (no value)



Subject: Use of Contextual::Return causes issues
Contextual::Return being loaded can cause other modules to break in some cases. One such case is MooseX::NonMoose when used with the perl debugger on perl 5.14. Contextual::Return and Want.pm can also cause segfaults. Contextual::Return is a rather heavy solution and its full power isn't really needed for this module. Attached is a patch that implements a minimal solution using a class with overloads.
Subject: boolean-no-cr.patch
diff --git i/lib/DBIx/Class/InflateColumn/Boolean.pm w/lib/DBIx/Class/InflateColumn/Boolean.pm index 114a80d..b4a666f 100644 --- i/lib/DBIx/Class/InflateColumn/Boolean.pm +++ w/lib/DBIx/Class/InflateColumn/Boolean.pm @@ -171,21 +171,21 @@ sub register_column { $ref eq '' ? sub { my $x = shift; - BLESSED { 'Contextual::Return::Value' } SCALAR { $x } BOOL { $x eq $false_is ? 0 : 1 }; + DBIx::Class::InflateColumn::Boolean::Value->new($x, $x ne $false_is); } : $ref eq 'ARRAY' ? sub { my $x = shift; for (@$false_is) { - return BLESSED { 'Contextual::Return::Value' } SCALAR { $x } BOOL { 0 } + return DBIx::Class::InflateColumn::Boolean::Value->new($x, 0) if $x eq $_; } - BLESSED { 'Contextual::Return::Value' } SCALAR { $x } BOOL { 1 }; + DBIx::Class::InflateColumn::Boolean::Value->new($x, 1) } : # $ref eq 'Regexp' sub { my $x = shift; - BLESSED { 'Contextual::Return::Value' } SCALAR { $x } BOOL { $x =~ $false_is ? 0 : 1 }; + DBIx::Class::InflateColumn::Boolean::Value->new($x, $x !~ $false_is); }, deflate => sub { shift }, } @@ -199,21 +199,21 @@ sub register_column { $ref eq '' ? sub { my $x = shift; - BLESSED { 'Contextual::Return::Value' } SCALAR { $x } BOOL { $x eq $true_is ? 1 : 0 }; + DBIx::Class::InflateColumn::Boolean::Value->new($x, $x eq $true_is); } : $ref eq 'ARRAY' ? sub { my $x = shift; for (@$true_is) { - return BLESSED { 'Contextual::Return::Value' } SCALAR { $x } BOOL { 1 } + return DBIx::Class::InflateColumn::Boolean::Value->new($x, 1) if $x eq $_; } - BLESSED { 'Contextual::Return::Value' } SCALAR { $x } BOOL { 0 }; + DBIx::Class::InflateColumn::Boolean::Value->new($x, 0) } : # $ref eq 'Regexp' sub { my $x = shift; - BLESSED { 'Contextual::Return::Value' } SCALAR { $x } BOOL { $x =~ $true_is ? 1 : 0 }; + DBIx::Class::InflateColumn::Boolean::Value->new($x, $x =~ $true_is) }, deflate => sub { shift }, } @@ -221,6 +221,22 @@ sub register_column { } } +{ + package #hide + DBIx::Class::InflateColumn::Boolean::Value; + + use overload + '""' => sub { $_[0][0] }, + 'bool' => sub { $_[0][1] }, + fallback => 1, + ; + + sub new { + my ($class, $value, $bool) = @_; + my $self = bless [$value, !!$bool], $class; + } +} + 1; __END__ diff --git i/t/01-boolean.t w/t/01-boolean.t index 7877826..94422e7 100644 --- i/t/01-boolean.t +++ w/t/01-boolean.t @@ -38,9 +38,9 @@ ok(blessed($true->foo), '$true->foo has been inflated into an object'); ok(blessed($true->bar), '$true->bar has been inflated into an object'); ok(blessed($true->baz), '$true->baz has been inflated into an object'); -ok(blessed($true->foo) && ref($true->foo) eq 'Contextual::Return::Value', 'ref($true->foo) eq "Contextual::Return::Value"'); -ok(blessed($true->bar) && ref($true->bar) eq 'Contextual::Return::Value', 'ref($true->bar) eq "Contextual::Return::Value"'); -ok(blessed($true->baz) && ref($true->baz) eq 'Contextual::Return::Value', 'ref($true->baz) eq "Contextual::Return::Value"'); +ok(blessed($true->foo) && ref($true->foo) eq 'DBIx::Class::InflateColumn::Boolean::Value', 'ref($true->foo) eq "DBIx::Class::InflateColumn::Boolean::Value"'); +ok(blessed($true->bar) && ref($true->bar) eq 'DBIx::Class::InflateColumn::Boolean::Value', 'ref($true->bar) eq "DBIx::Class::InflateColumn::Boolean::Value"'); +ok(blessed($true->baz) && ref($true->baz) eq 'DBIx::Class::InflateColumn::Boolean::Value', 'ref($true->baz) eq "DBIx::Class::InflateColumn::Boolean::Value"'); is($true->foo, 'Y', '$true->foo eq "Y"'); is($true->bar, 'oui', '$true->bar eq "oui"'); @@ -54,9 +54,9 @@ ok(blessed($false->foo), '$false->foo has been inflated into an object'); ok(blessed($false->bar), '$false->bar has been inflated into an object'); ok(blessed($false->baz), '$false->baz has been inflated into an object'); -ok(blessed($false->foo) && ref($false->foo) eq 'Contextual::Return::Value', 'ref($true->foo) eq "Contextual::Return::Value"'); -ok(blessed($false->bar) && ref($false->bar) eq 'Contextual::Return::Value', 'ref($true->bar) eq "Contextual::Return::Value"'); -ok(blessed($false->baz) && ref($false->baz) eq 'Contextual::Return::Value', 'ref($true->baz) eq "Contextual::Return::Value"'); +ok(blessed($false->foo) && ref($false->foo) eq 'DBIx::Class::InflateColumn::Boolean::Value', 'ref($true->foo) eq "DBIx::Class::InflateColumn::Boolean::Value"'); +ok(blessed($false->bar) && ref($false->bar) eq 'DBIx::Class::InflateColumn::Boolean::Value', 'ref($true->bar) eq "DBIx::Class::InflateColumn::Boolean::Value"'); +ok(blessed($false->baz) && ref($false->baz) eq 'DBIx::Class::InflateColumn::Boolean::Value', 'ref($true->baz) eq "DBIx::Class::InflateColumn::Boolean::Value"'); is($false->foo, 'N', '$false->foo eq "N"'); is($false->bar, 'non', '$false->bar eq "non"'); @@ -71,7 +71,7 @@ $false->update; my $row = $rs->find(2); # re-read 2nd row ok(blessed($row->bar), '$row->bar has been inflated into an object'); -ok(blessed($row->bar) && ref($row->bar) eq 'Contextual::Return::Value', 'ref($row->bar) eq "Contextual::Return::Value"'); +ok(blessed($row->bar) && ref($row->bar) eq 'DBIx::Class::InflateColumn::Boolean::Value', 'ref($row->bar) eq "DBIx::Class::InflateColumn::Boolean::Value"'); is($row->bar, 'oui', '$row->bar eq "oui"'); ok($row->bar, '$true->bar is row'); ok(!blessed($row->get_column('bar')), '$row->get_column("bar") is not blessed');
Here's an updates patch that removes the actual loading of Contextual::Return, as well as removing it from the Makefile.PL and docs.
Subject: boolean-no-cr.patch
diff --git i/Makefile.PL w/Makefile.PL index 8688623..33dab87 100644 --- i/Makefile.PL +++ w/Makefile.PL @@ -6,7 +6,6 @@ all_from 'lib/DBIx/Class/InflateColumn/Boolean.pm'; author 'Bernhard Graf <perl-misc@movingtarget.de>'; requires 'DBIx::Class' => 0.08; -requires 'Contextual::Return' => 0.004007; test_requires 'Test::More'; test_requires 'Scalar::Util'; diff --git i/lib/DBIx/Class/InflateColumn/Boolean.pm w/lib/DBIx/Class/InflateColumn/Boolean.pm index 114a80d..06143d7 100644 --- i/lib/DBIx/Class/InflateColumn/Boolean.pm +++ w/lib/DBIx/Class/InflateColumn/Boolean.pm @@ -5,8 +5,6 @@ use strict; use base qw/DBIx::Class/; -use Contextual::Return; - =head1 NAME DBIx::Class::InflateColumn::Boolean - Auto-create boolean objects from columns. @@ -65,20 +63,17 @@ But for a database it is up to the designer to decide what is C<true> and what is C<false>. This module maps such "database booleans" into "Perl booleans" and back -by inflating designated columns into some sort of boolean objects, that -happen to be instances of L<Contextual::Return::Value|Contextual::Return>. -Objects of this class can store the original value and a boolean meaning -at the same time. Therefore - if C<Yes> in the database means C<true> -and C<No> means C<false> in the application the following two lines can -virtually mean the same: +by inflating designated columns into objects that store the original value, +but also evaluate as true or false in boolean context. Therefore - if +C<Yes> in the database means C<true> and C<No> means C<false> in the +application the following two lines can virtually mean the same: if ($table->field eq "No") { ... } if (not $table->field) { ... } That means that C<< $table->field >> has the scalar value C<"No">, but -is taken as C<false> in a boolean context, whereas without the little -magic from L<Contextual::Return|Contextual::Return> Perl would regard -the string C<"No"> as C<true>. +is taken as C<false> in a boolean context, whereas Perl would normally +regardthe string C<"No"> as C<true>. When writing to the database, of course C<< $table->field >> would be deflated to the original value C<"No"> and not some Perlish form of a @@ -86,16 +81,14 @@ boolean. =head2 Important Notice -It is strongly discouraged to assign a -L<Contextual::Return|Contextual::Return> object to a boolean field when -creating a fresh row, because: +It is strongly encouraged to assign normal database values to a boolean +field when creating a fresh row, because: =over 4 =item KISS (http://en.wikipedia.org/wiki/KISS_principle) -Just say "No" when you mean it. It does not buy you anything to say -C<SCALAR {"No"} BOOL { 0 }>. +Just say "No" when you mean it. =item Don't rely on the current boolean class @@ -171,21 +164,21 @@ sub register_column { $ref eq '' ? sub { my $x = shift; - BLESSED { 'Contextual::Return::Value' } SCALAR { $x } BOOL { $x eq $false_is ? 0 : 1 }; + DBIx::Class::InflateColumn::Boolean::Value->new($x, $x ne $false_is); } : $ref eq 'ARRAY' ? sub { my $x = shift; for (@$false_is) { - return BLESSED { 'Contextual::Return::Value' } SCALAR { $x } BOOL { 0 } + return DBIx::Class::InflateColumn::Boolean::Value->new($x, 0) if $x eq $_; } - BLESSED { 'Contextual::Return::Value' } SCALAR { $x } BOOL { 1 }; + DBIx::Class::InflateColumn::Boolean::Value->new($x, 1) } : # $ref eq 'Regexp' sub { my $x = shift; - BLESSED { 'Contextual::Return::Value' } SCALAR { $x } BOOL { $x =~ $false_is ? 0 : 1 }; + DBIx::Class::InflateColumn::Boolean::Value->new($x, $x !~ $false_is); }, deflate => sub { shift }, } @@ -199,21 +192,21 @@ sub register_column { $ref eq '' ? sub { my $x = shift; - BLESSED { 'Contextual::Return::Value' } SCALAR { $x } BOOL { $x eq $true_is ? 1 : 0 }; + DBIx::Class::InflateColumn::Boolean::Value->new($x, $x eq $true_is); } : $ref eq 'ARRAY' ? sub { my $x = shift; for (@$true_is) { - return BLESSED { 'Contextual::Return::Value' } SCALAR { $x } BOOL { 1 } + return DBIx::Class::InflateColumn::Boolean::Value->new($x, 1) if $x eq $_; } - BLESSED { 'Contextual::Return::Value' } SCALAR { $x } BOOL { 0 }; + DBIx::Class::InflateColumn::Boolean::Value->new($x, 0) } : # $ref eq 'Regexp' sub { my $x = shift; - BLESSED { 'Contextual::Return::Value' } SCALAR { $x } BOOL { $x =~ $true_is ? 1 : 0 }; + DBIx::Class::InflateColumn::Boolean::Value->new($x, $x =~ $true_is) }, deflate => sub { shift }, } @@ -221,6 +214,22 @@ sub register_column { } } +{ + package #hide + DBIx::Class::InflateColumn::Boolean::Value; + + use overload + '""' => sub { $_[0][0] }, + 'bool' => sub { $_[0][1] }, + fallback => 1, + ; + + sub new { + my ($class, $value, $bool) = @_; + my $self = bless [$value, !!$bool], $class; + } +} + 1; __END__ diff --git i/t/01-boolean.t w/t/01-boolean.t index 7877826..94422e7 100644 --- i/t/01-boolean.t +++ w/t/01-boolean.t @@ -38,9 +38,9 @@ ok(blessed($true->foo), '$true->foo has been inflated into an object'); ok(blessed($true->bar), '$true->bar has been inflated into an object'); ok(blessed($true->baz), '$true->baz has been inflated into an object'); -ok(blessed($true->foo) && ref($true->foo) eq 'Contextual::Return::Value', 'ref($true->foo) eq "Contextual::Return::Value"'); -ok(blessed($true->bar) && ref($true->bar) eq 'Contextual::Return::Value', 'ref($true->bar) eq "Contextual::Return::Value"'); -ok(blessed($true->baz) && ref($true->baz) eq 'Contextual::Return::Value', 'ref($true->baz) eq "Contextual::Return::Value"'); +ok(blessed($true->foo) && ref($true->foo) eq 'DBIx::Class::InflateColumn::Boolean::Value', 'ref($true->foo) eq "DBIx::Class::InflateColumn::Boolean::Value"'); +ok(blessed($true->bar) && ref($true->bar) eq 'DBIx::Class::InflateColumn::Boolean::Value', 'ref($true->bar) eq "DBIx::Class::InflateColumn::Boolean::Value"'); +ok(blessed($true->baz) && ref($true->baz) eq 'DBIx::Class::InflateColumn::Boolean::Value', 'ref($true->baz) eq "DBIx::Class::InflateColumn::Boolean::Value"'); is($true->foo, 'Y', '$true->foo eq "Y"'); is($true->bar, 'oui', '$true->bar eq "oui"'); @@ -54,9 +54,9 @@ ok(blessed($false->foo), '$false->foo has been inflated into an object'); ok(blessed($false->bar), '$false->bar has been inflated into an object'); ok(blessed($false->baz), '$false->baz has been inflated into an object'); -ok(blessed($false->foo) && ref($false->foo) eq 'Contextual::Return::Value', 'ref($true->foo) eq "Contextual::Return::Value"'); -ok(blessed($false->bar) && ref($false->bar) eq 'Contextual::Return::Value', 'ref($true->bar) eq "Contextual::Return::Value"'); -ok(blessed($false->baz) && ref($false->baz) eq 'Contextual::Return::Value', 'ref($true->baz) eq "Contextual::Return::Value"'); +ok(blessed($false->foo) && ref($false->foo) eq 'DBIx::Class::InflateColumn::Boolean::Value', 'ref($true->foo) eq "DBIx::Class::InflateColumn::Boolean::Value"'); +ok(blessed($false->bar) && ref($false->bar) eq 'DBIx::Class::InflateColumn::Boolean::Value', 'ref($true->bar) eq "DBIx::Class::InflateColumn::Boolean::Value"'); +ok(blessed($false->baz) && ref($false->baz) eq 'DBIx::Class::InflateColumn::Boolean::Value', 'ref($true->baz) eq "DBIx::Class::InflateColumn::Boolean::Value"'); is($false->foo, 'N', '$false->foo eq "N"'); is($false->bar, 'non', '$false->bar eq "non"'); @@ -71,7 +71,7 @@ $false->update; my $row = $rs->find(2); # re-read 2nd row ok(blessed($row->bar), '$row->bar has been inflated into an object'); -ok(blessed($row->bar) && ref($row->bar) eq 'Contextual::Return::Value', 'ref($row->bar) eq "Contextual::Return::Value"'); +ok(blessed($row->bar) && ref($row->bar) eq 'DBIx::Class::InflateColumn::Boolean::Value', 'ref($row->bar) eq "DBIx::Class::InflateColumn::Boolean::Value"'); is($row->bar, 'oui', '$row->bar eq "oui"'); ok($row->bar, '$true->bar is row'); ok(!blessed($row->get_column('bar')), '$row->get_column("bar") is not blessed');
I've applied the patch and removed another Contextual::Return mention in the docs and sent a github pull-request.
Show quoted text
> I've applied the patch and removed another Contextual::Return mention > in the docs and sent a github pull-request.
Merged and released as 0.003000. Thanks haarg and abraxxa.