Skip to content

Instantly share code, notes, and snippets.

@SpiceMan
Last active August 29, 2015 14:08
Show Gist options
  • Save SpiceMan/3801773e03e4555f0b9b to your computer and use it in GitHub Desktop.
Save SpiceMan/3801773e03e4555f0b9b to your computer and use it in GitHub Desktop.
#!/usr/bin/env perl
use strict;
use warnings;
use feature qw/:5.10/;
use Moops;
use Carp::Always;
role SubClassVariableAttributes {
has "_var_attrs" => qw/is rw isa HashRef required 1/;
method BUILD {}
around BUILD {
my $args = shift;
my $var_attrs = delete $self->{_var_attrs};
for my $attr ( keys %$var_attrs ) {
$self->meta->add_attribute( $attr, $var_attrs->{$attr} );
$self->$attr( $args->{$attr} ) if defined $args->{$attr};
$self->meta->remove_attribute("_var_attrs");
}
$self->$next(@_);
}
}
class Foo with SubClassVariableAttributes {
has "value" => qw/is rw isa Str lazy_build 1/;
method _build_value {
return join(", ", map { $_->name . ": ". $self->{ $_->name } } grep { $_->name !~ /value/ } $self->meta->get_all_attributes );
}
}
class Bar extends Foo {
around BUILDARGS {
my $args = shift;
$args->{_var_attrs}{$_} = {qw/is rw isa Str/} for qw/foo bar baz/;
return $self->$next($args);
}
}
my $bar = Bar->new({ foo => 1, bar => 2, baz => 3 });
say $bar->value;
__DATA__
===================
= MODULE VERSIONS =
===================
Moo
/opt/perl5/perls/perl-5.18.2/lib/site_perl/5.18.2/Moo.pm: 1.006000
Kavorka
/opt/perl5/perls/perl-5.18.2/lib/site_perl/5.18.2/Kavorka.pm: 0.035
Moops
/opt/perl5/perls/perl-5.18.2/lib/site_perl/5.18.2/Moops.pm: 0.034
Sub::Defer
/opt/perl5/perls/perl-5.18.2/lib/site_perl/5.18.2/Sub/Defer.pm: 1.006000
12:22 spiceman@cynic ~/workspace/MoopsTestCase % perl a.pl ; until [ $? -ne 0 ]; do perl a.pl; done
bar: 2, foo: 1, baz: 3, _var_attrs:
_var_attrs: , foo: 1, bar: 2, baz: 3
baz: 3, bar: 2, _var_attrs: , foo: 1
foo: 1, bar: 2, _var_attrs: , baz: 3
_var_attrs: , bar: 2, baz: 3, foo: 1
bar: 2, foo: 1, baz: 3, _var_attrs:
baz: 3, _var_attrs: , foo: 1, bar: 2
_var_attrs: , baz: 3, bar: 2, foo: 1
bar: 2, baz: 3, foo: 1, _var_attrs:
baz: 3, _var_attrs: , foo: 1, bar: 2
foo: 1, _var_attrs: , bar: 2, baz: 3
foo: 1, baz: 3, bar: 2, _var_attrs:
baz: 3, bar: 2, foo: 1, _var_attrs:
baz: 3, foo: 1, bar: 2, _var_attrs:
_var_attrs: , bar: 2, baz: 3, foo: 1
_var_attrs: , bar: 2, foo: 1, baz: 3
foo: 1, _var_attrs: , baz: 3, bar: 2
baz: 3, _var_attrs: , bar: 2, foo: 1
bar: 2, foo: 1, _var_attrs: , baz: 3
_var_attrs: , baz: 3, foo: 1, bar: 2
bar: 2, foo: 1, baz: 3, _var_attrs:
_var_attrs: , bar: 2, baz: 3, foo: 1
foo: 1, baz: 3, _var_attrs: , bar: 2
baz: 3, bar: 2, foo: 1, _var_attrs:
baz: 3, bar: 2, foo: 1, _var_attrs:
bar: 2, baz: 3, foo: 1, _var_attrs:
foo: 1, baz: 3, _var_attrs: , bar: 2
bar: 2, _var_attrs: , baz: 3, foo: 1
baz: 3, _var_attrs: , foo: 1, bar: 2
_var_attrs: , bar: 2, foo: 1, baz: 3
foo: 1, bar: 2, _var_attrs: , baz: 3
foo: 1, baz: 3, _var_attrs: , bar: 2
baz: 3, _var_attrs: , bar: 2, foo: 1
foo: 1, _var_attrs: , bar: 2, baz: 3
bar: 2, baz: 3, _var_attrs: , foo: 1
baz: 3, bar: 2, _var_attrs: , foo: 1
_var_attrs: , foo: 1, bar: 2, baz: 3
_var_attrs: , baz: 3, bar: 2, foo: 1
bar: 2, foo: 1, baz: 3, _var_attrs:
bar: 2, _var_attrs: , baz: 3, foo: 1
baz: 3, _var_attrs: , bar: 2, foo: 1
bar: 2, baz: 3, foo: 1, _var_attrs:
baz: 3, bar: 2, foo: 1, _var_attrs:
bar: 2, foo: 1, _var_attrs: , baz: 3
_var_attrs: , foo: 1, baz: 3, bar: 2
foo: 1, _var_attrs: , bar: 2, baz: 3
baz: 3, foo: 1, bar: 2, _var_attrs:
_var_attrs: , foo: 1, baz: 3, bar: 2
foo: 1, baz: 3, bar: 2, _var_attrs:
foo: 1, _var_attrs: , baz: 3, bar: 2
_var_attrs: , foo: 1, baz: 3, bar: 2
bar: 2, _var_attrs: , foo: 1, baz: 3
_var_attrs: , baz: 3, foo: 1, bar: 2
bar: 2, _var_attrs: , foo: 1, baz: 3
bar: 2, baz: 3, foo: 1, _var_attrs:
foo: 1, baz: 3, bar: 2, _var_attrs:
bar: 2, foo: 1, _var_attrs: , baz: 3
_var_attrs: , foo: 1, bar: 2, baz: 3
baz: 3, bar: 2, _var_attrs: , foo: 1
_var_attrs: , foo: 1, baz: 3, bar: 2
_var_attrs: , bar: 2, foo: 1, baz: 3
_var_attrs: , foo: 1, baz: 3, bar: 2
bar: 2, baz: 3, _var_attrs: , foo: 1
baz: 3, bar: 2, foo: 1, _var_attrs:
baz: 3, _var_attrs: , foo: 1, bar: 2
bar: 2, foo: 1, baz: 3, _var_attrs:
baz: 3, foo: 1, bar: 2, _var_attrs:
baz: 3, _var_attrs: , bar: 2, foo: 1
bar: 2, baz: 3, _var_attrs: , foo: 1
bar: 2, baz: 3, _var_attrs: , foo: 1
foo: 1, baz: 3, bar: 2, _var_attrs:
bar: 2, baz: 3, foo: 1, _var_attrs:
bar: 2, _var_attrs: , baz: 3, foo: 1
foo: 1, baz: 3, _var_attrs: , bar: 2
bar: 2, baz: 3, _var_attrs: , foo: 1
bar: 2, _var_attrs: , baz: 3, foo: 1
foo: 1, _var_attrs: , bar: 2, baz: 3
foo: 1, _var_attrs: , baz: 3, bar: 2
baz: 3, foo: 1, bar: 2, _var_attrs:
_var_attrs: , baz: 3, foo: 1, bar: 2
bar: 2, _var_attrs: , foo: 1, baz: 3
baz: 3, foo: 1, _var_attrs: , bar: 2
baz: 3, bar: 2, foo: 1, _var_attrs:
baz: 3, _var_attrs: , foo: 1, bar: 2
foo: 1, bar: 2, baz: 3, _var_attrs:
baz: 3, _var_attrs: , foo: 1, bar: 2
baz: 3, bar: 2, foo: 1, _var_attrs:
_var_attrs: , foo: 1, baz: 3, bar: 2
_var_attrs: , foo: 1, bar: 2, baz: 3
foo: 1, _var_attrs: , bar: 2, baz: 3
baz: 3, foo: 1, bar: 2, _var_attrs:
baz: 3, bar: 2, foo: 1, _var_attrs:
bar: 2, _var_attrs: , foo: 1, baz: 3
bar: 2, baz: 3, foo: 1, _var_attrs:
baz: 3, _var_attrs: , bar: 2, foo: 1
foo: 1, bar: 2, _var_attrs: , baz: 3
bar: 2, foo: 1, baz: 3, _var_attrs:
foo: 1, _var_attrs: , baz: 3, bar: 2
foo: 1, bar: 2, baz: 3, _var_attrs:
baz: 3, bar: 2, _var_attrs: , foo: 1
bar: 2, foo: 1, _var_attrs: , baz: 3
baz: 3, bar: 2, _var_attrs: , foo: 1
_var_attrs: , foo: 1, bar: 2, baz: 3
bar: 2, baz: 3, foo: 1, _var_attrs:
bar: 2, baz: 3, _var_attrs: , foo: 1
baz: 3, foo: 1, _var_attrs: , bar: 2
baz: 3, foo: 1, _var_attrs: , bar: 2
_var_attrs: , bar: 2, foo: 1, baz: 3
bar: 2, _var_attrs: , foo: 1, baz: 3
bar: 2, baz: 3, foo: 1, _var_attrs:
baz: 3, bar: 2, _var_attrs: , foo: 1
_var_attrs: , bar: 2, foo: 1, baz: 3
foo: 1, bar: 2, baz: 3, _var_attrs:
_var_attrs: , foo: 1, bar: 2, baz: 3
foo: 1, bar: 2, baz: 3, _var_attrs:
foo: 1, bar: 2, _var_attrs: , baz: 3
baz: 3, foo: 1, _var_attrs: , bar: 2
baz: 3, foo: 1, bar: 2, _var_attrs:
_var_attrs: , bar: 2, baz: 3, foo: 1
foo: 1, baz: 3, bar: 2, _var_attrs:
_var_attrs: , foo: 1, baz: 3, bar: 2
baz: 3, foo: 1, bar: 2, _var_attrs:
bar: 2, _var_attrs: , foo: 1, baz: 3
foo: 1, bar: 2, baz: 3, _var_attrs:
foo: 1, _var_attrs: , baz: 3, bar: 2
bar: 2, foo: 1, baz: 3, _var_attrs:
_var_attrs: , foo: 1, baz: 3, bar: 2
foo: 1, baz: 3, _var_attrs: , bar: 2
_var_attrs: , bar: 2, foo: 1, baz: 3
baz: 3, _var_attrs: , bar: 2, foo: 1
foo: 1, baz: 3, _var_attrs: , bar: 2
foo: 1, bar: 2, _var_attrs: , baz: 3
baz: 3, foo: 1, bar: 2, _var_attrs:
bar: 2, _var_attrs: , foo: 1, baz: 3
_var_attrs: , baz: 3, foo: 1, bar: 2
bar: 2, foo: 1, baz: 3, _var_attrs:
bar: 2, foo: 1, baz: 3, _var_attrs:
_var_attrs: , foo: 1, bar: 2, baz: 3
foo: 1, bar: 2, _var_attrs: , baz: 3
_var_attrs: , bar: 2, foo: 1, baz: 3
_var_attrs: , baz: 3, bar: 2, foo: 1
_var_attrs: , foo: 1, baz: 3, bar: 2
baz: 3, bar: 2, _var_attrs: , foo: 1
_var_attrs: , baz: 3, bar: 2, foo: 1
bar: 2, _var_attrs: , baz: 3, foo: 1
foo: 1, baz: 3, bar: 2, _var_attrs:
_var_attrs: , foo: 1, baz: 3, bar: 2
_var_attrs: , bar: 2, foo: 1, baz: 3
baz: 3, bar: 2, _var_attrs: , foo: 1
_var_attrs: , baz: 3, bar: 2, foo: 1
_var_attrs: , bar: 2, foo: 1, baz: 3
baz: 3, bar: 2, foo: 1, _var_attrs:
foo: 1, bar: 2, _var_attrs: , baz: 3
baz: 3, _var_attrs: , foo: 1, bar: 2
baz: 3, bar: 2, _var_attrs: , foo: 1
baz: 3, _var_attrs: , bar: 2, foo: 1
baz: 3, foo: 1, bar: 2, _var_attrs:
bar: 2, baz: 3, _var_attrs: , foo: 1
foo: 1, bar: 2, _var_attrs: , baz: 3
baz: 3, foo: 1, bar: 2, _var_attrs:
_var_attrs: , foo: 1, baz: 3, bar: 2
_var_attrs: , foo: 1, bar: 2, baz: 3
baz: 3, _var_attrs: , bar: 2, foo: 1
bar: 2, _var_attrs: , foo: 1, baz: 3
baz: 3, _var_attrs: , bar: 2, foo: 1
baz: 3, _var_attrs: , bar: 2, foo: 1
bar: 2, foo: 1, _var_attrs: , baz: 3
baz: 3, _var_attrs: , foo: 1, bar: 2
_var_attrs: , baz: 3, bar: 2, foo: 1
baz: 3, _var_attrs: , foo: 1, bar: 2
Can't use an undefined value as a SCALAR reference at /opt/perl5/perls/perl-5.18.2/lib/site_perl/5.18.2/Sub/Defer.pm line 21.
Sub::Defer::undefer_sub(CODE(0x26abea8)) called at /opt/perl5/perls/perl-5.18.2/lib/site_perl/5.18.2/Moo/HandleMoose.pm line 95
Moo::HandleMoose::inject_real_metaclass_for("Foo") called at /opt/perl5/perls/perl-5.18.2/lib/site_perl/5.18.2/Moo/HandleMoose/FakeMetaClass.pm line 9
Moo::HandleMoose::FakeMetaClass::AUTOLOAD(Moo::HandleMoose::FakeMetaClass=HASH(0x30fdb58)) called at /opt/perl5/perls/perl-5.18.2/lib/site_perl/5.18.2/x86_64-linux/Class/MOP/Class.pm line 334
Class::MOP::Class::_class_metaclass_can_be_made_compatible(Moose::Meta::Class=HASH(0x30fd840), Moo::HandleMoose::FakeMetaClass=HASH(0x30fdb58)) called at /opt/perl5/perls/perl-5.18.2/lib/site_perl/5.18.2/x86_64-linux/Class/MOP/Class.pm line 320
Class::MOP::Class::_can_fix_metaclass_incompatibility(Moose::Meta::Class=HASH(0x30fd840), Moo::HandleMoose::FakeMetaClass=HASH(0x30fdb58)) called at /opt/perl5/perls/perl-5.18.2/lib/site_perl/5.18.2/x86_64-linux/Class/MOP/Class.pm line 293
Class::MOP::Class::_fix_metaclass_incompatibility(Moose::Meta::Class=HASH(0x30fd840), "Foo") called at /opt/perl5/perls/perl-5.18.2/lib/site_perl/5.18.2/x86_64-linux/Class/MOP/Class.pm line 198
Class::MOP::Class::_check_metaclass_compatibility(Moose::Meta::Class=HASH(0x30fd840)) called at /opt/perl5/perls/perl-5.18.2/lib/site_perl/5.18.2/x86_64-linux/Class/MOP/Class.pm line 103
Class::MOP::Class::_construct_class_instance("Moose::Meta::Class", "package", "Bar", "attribute_metaclass", "Moose::Meta::Attribute", "method_metaclass", "Moose::Meta::Method", "instance_metaclass", "Moose::Meta::Instance", ...) called at /opt/perl5/perls/perl-5.18.2/lib/site_perl/5.18.2/x86_64-linux/Class/MOP/Class.pm line 39
Class::MOP::Class::initialize("Moose::Meta::Class", "Bar", "attribute_metaclass", "Moose::Meta::Attribute", "method_metaclass", "Moose::Meta::Method", "instance_metaclass", "Moose::Meta::Instance") called at /opt/perl5/perls/perl-5.18.2/lib/site_perl/5.18.2/x86_64-linux/Moose/Meta/Class.pm line 64
Moose::Meta::Class::initialize("Moose::Meta::Class", "Bar") called at /opt/perl5/perls/perl-5.18.2/lib/site_perl/5.18.2/Moo/HandleMoose.pm line 70
Moo::HandleMoose::inject_real_metaclass_for("Bar") called at /opt/perl5/perls/perl-5.18.2/lib/site_perl/5.18.2/Moo/HandleMoose/FakeMetaClass.pm line 9
Moo::HandleMoose::FakeMetaClass::AUTOLOAD(Moo::HandleMoose::FakeMetaClass=HASH(0x1b71560), "foo", HASH(0x26d6500)) called at a.pl line 22
SubClassVariableAttributes::BUILD(CODE(0x25b9f58), Bar=HASH(0x1b71530), HASH(0x172de28)) called at (eval 194) line 1
Foo::__ANON__(Bar=HASH(0x1b71530), HASH(0x172de28)) called at (eval 196) line 2
Foo::BUILD(Bar=HASH(0x1b71530), HASH(0x172de28)) called at (eval 204) line 108
Bar::new(undef, HASH(0x14b3fc8)) called at (eval 203) line 25
Foo::new("Bar", HASH(0x14b3fc8)) called at a.pl line 55
=========================================================================
Summary of my perl5 (revision 5 version 18 subversion 2) configuration:
Platform:
osname=linux, osvers=3.2.0-4-amd64, archname=x86_64-linux
uname='linux webserver 3.2.0-4-amd64 #1 smp debian 3.2.54-2 x86_64 gnulinux '
config_args='-de -Dprefix=/opt/perl5/perls/perl-5.18.2 -Aeval:scriptdir=/opt/perl5/perls/perl-5.18.2/bin'
hint=recommended, useposix=true, d_sigaction=define
useithreads=undef, usemultiplicity=undef
useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
use64bitint=define, use64bitall=define, uselongdouble=undef
usemymalloc=n, bincompat5005=undef
Compiler:
cc='cc', ccflags ='-fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
optimize='-O2',
cppflags='-fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include'
ccversion='', gccversion='4.7.2', gccosandvers=''
intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678
d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16
ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
alignbytes=8, prototype=define
Linker and Libraries:
ld='cc', ldflags =' -fstack-protector -L/usr/local/lib'
libpth=/usr/local/lib /lib/x86_64-linux-gnu /lib/../lib /usr/lib/x86_64-linux-gnu /usr/lib/../lib /lib /usr/lib
libs=-lnsl -ldl -lm -lcrypt -lutil -lc
perllibs=-lnsl -ldl -lm -lcrypt -lutil -lc
libc=libc-2.13.so, so=so, useshrplib=false, libperl=libperl.a
gnulibc_version='2.13'
Dynamic Linking:
dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E'
cccdlflags='-fPIC', lddlflags='-shared -O2 -L/usr/local/lib -fstack-protector'
Characteristics of this binary (from libperl):
Compile-time options: HAS_TIMES PERLIO_LAYERS PERL_DONT_CREATE_GVSV
PERL_HASH_FUNC_ONE_AT_A_TIME_HARD PERL_MALLOC_WRAP
PERL_PRESERVE_IVUV PERL_SAWAMPERSAND USE_64_BIT_ALL
USE_64_BIT_INT USE_LARGE_FILES USE_LOCALE
USE_LOCALE_COLLATE USE_LOCALE_CTYPE
USE_LOCALE_NUMERIC USE_PERLIO USE_PERL_ATOF
Built under linux
Compiled at Mar 12 2014 20:12:57
%ENV:
PERLBREW_BASHRC_VERSION="0.67"
PERLBREW_HOME="/opt/.perlbrew"
PERLBREW_MANPATH="/opt/perl5/perls/perl-5.18.2/man"
PERLBREW_PATH="/opt/perl5/bin:/opt/perl5/perls/perl-5.18.2/bin"
PERLBREW_PERL="perl-5.18.2"
PERLBREW_ROOT="/opt/perl5"
PERLBREW_VERSION="0.67"
@INC:
/opt/perl5/perls/perl-5.18.2/lib/site_perl/5.18.2/x86_64-linux
/opt/perl5/perls/perl-5.18.2/lib/site_perl/5.18.2
/opt/perl5/perls/perl-5.18.2/lib/5.18.2/x86_64-linux
/opt/perl5/perls/perl-5.18.2/lib/5.18.2
.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment