Skip Menu |

This queue is for tickets about the Class-Std CPAN distribution.

Report information
The Basics
Id: 46409
Status: new
Priority: 0/
Queue: Class-Std

People
Owner: Nobody in particular
Requestors: binarin [...] binarin.ru
Cc:
AdminCc:

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



Subject: Method can't be PROTECTED and CUMULATIVE simultaneously
Compilation of attached stdtest.pl fails with error: Can't make anonymous subroutine cumulative at stdtest.pl line 0 It's because _find_sub() can't find already replaced sub in symbol table. To fix it, _find_sub() must cache symbol lookups, as in attached version. Also, order of initialization must be changed: e.g., RESTRICTED attributes must be applied after CUMULATIVE ones. In find_sub.pl attach there is fixed version. Probably, this _find_sub() must be factored out in separate module, which will be used both by Class::Std and other attribute-using sub-redefining modules.
Subject: stdtest.pl
#!/usr/bin/perl # -*- encoding: utf-8; tab-width: 8 -*- use strict; use warnings; use utf8; use Carp; use English '-no_match_vars'; use version; our $VERSION = qv('1.0.0'); package Wax::Floor; use Class::Std; { my %name_of :ATTR( init_arg => 'name' ); my %patent_of :ATTR( init_arg => 'patent' ); sub real_describe { my ( $self ) = @_; $self->describe; } sub describe :CUMULATIVE RESTRICTED { my ($self) = @_; print "The floor wax $name_of{ident $self} ", "(patent: $patent_of{ident $self})\n"; return; } } package Topping::Dessert; use Class::Std; { my %name_of :ATTR( init_arg => 'name' ); my %flavour_of :ATTR( init_arg => 'flavour' ); sub describe :CUMULATIVE RESTRICTED { my ($self) = @_; print "The dessert topping $name_of{ident $self} ", "with that great $flavour_of{ident $self} taste!\n"; return; } } package Shimmer; use base qw( Wax::Floor Topping::Dessert ); use Class::Std; { my %name_of :ATTR( init_arg => 'name' ); my %patent_of :ATTR( init_arg => 'patent' ); sub describe :CUMULATIVE RESTRICTED { my ($self) = @_; print "New $name_of{ident $self} ", "(patent: $patent_of{ident $self})\n", "Combining...\n"; return; } } package main; my $product = Shimmer->new({ name => 'Shimmer', patent => 1562516251, flavour => 'Vanilla', }); $product->real_describe();
Subject: find_sub.pl
my %_find_sub_cache; sub _find_sub { my ($package, $sub_ref) = @_; no strict 'refs'; if (my $it = $_find_sub_cache{$package}{$sub_ref}) { return $it; } for my $name (keys %{$package.'::'}) { my $candidate = *{$package.'::'.$name}{CODE}; if ($candidate && $candidate == $sub_ref) { $_find_sub_cache{$package}{$sub_ref} = $name; return $name; } } croak q{Can't make anonymous subroutine cumulative}; }