Slide 1

Slide 1 text

Meta Object Protocol (MOP) Upasana [email protected]

Slide 2

Slide 2 text

About me ● Software developer at booking.com

Slide 3

Slide 3 text

We are hiring https://workingatbooking.com/

Slide 4

Slide 4 text

Backstory ● GNOME Outreach Program for Women internship in 2013 ● Structured exceptions in Moose ● Want to share whatever I learnt during my internship

Slide 5

Slide 5 text

Topics 1) Little bit about object oriented programming (OOP) 2) Little bit about OOP in perl (the old style) 3) Meta object protocol (MOP) 4) History of MOP 5) Applications of MOP

Slide 6

Slide 6 text

Topics 6) Implementing MOP in Perl (the easy way) 7) Why #6 might not be a good idea 8) Metaclass incompatibility 9) Mixins 10) MOP in Moose 11) Drawbacks of MOP 12) Where to go next?

Slide 7

Slide 7 text

How a class looks like? ● Class name ● Superclasses

Slide 8

Slide 8 text

How a class looks like? ● Attributes – is read only or read-write – type (int, float etc.) – default value if any – getter method (accessor) – setter method (mutator)

Slide 9

Slide 9 text

How a class looks like? ● Methods – method name – body

Slide 10

Slide 10 text

Classes in Perl ● Perl doesn't provide any special syntax for classes ● Perl packages are classes

Slide 11

Slide 11 text

Attributes in Perl classes ● No special syntax or support for declaring and manipulating attributes ● Attributes are stored in the object itself ● As a hash of key-value pairs

Slide 12

Slide 12 text

Object? ● A hash reference ● blessed into a class

Slide 13

Slide 13 text

OOP in Perl package Rectangle; sub new { my $self = shift; my $attributes = { @_ }; bless $attributes, $self; } Rectangle->new( height => 10, width => 20, );

Slide 14

Slide 14 text

OOP in Perl package Rectangle; sub new { my $self = shift; my $attributes = { @_ }; bless $attributes, $self; } Rectangle->new( height => 10, width => 20, );

Slide 15

Slide 15 text

OOP in Perl package Rectangle; sub new { my $self = shift; my $attributes = { @_ }; bless $attributes, $self; } Rectangle->new( height => 10, width => 20, );

Slide 16

Slide 16 text

OOP in Perl package Rectangle; sub new { my $self = shift; my $attributes = { @_ }; bless $attributes, $self; } Rectangle->new( height => 10, width => 20, );

Slide 17

Slide 17 text

OOP in Perl package Rectangle; sub new { my $self = shift; my $attributes = { @_ }; bless $attributes, $self; } Rectangle->new( height => 10, width => 20, );

Slide 18

Slide 18 text

OOP in Perl package Rectangle; sub new { my $self = shift; my $attributes = { @_ }; bless $attributes, $self; } Rectangle->new( height => 10, width => 20, );

Slide 19

Slide 19 text

OOP in Perl package Rectangle; sub new { my $self = shift; my $attributes = { @_ }; bless $attributes, $self; } Rectangle->new( height => 10, width => 20, );

Slide 20

Slide 20 text

What is MOP? ● provides the vocabulary to access and manipulate the structure and behavior of objects.

Slide 21

Slide 21 text

Functions of MOP ● Creating new classes ● Deleting existing classes ● Changing the class structure ● Changing methods of the class ● At runtime

Slide 22

Slide 22 text

History of MOP ● First introduced in the Smalltalk ● Common LISP Object System (CLOS) was influenced by Smalltalk ● CLOS allowed multiple inheritance unlike Smalltalk

Slide 23

Slide 23 text

MOP in modern languages ● Javascript has Joose ● OpenC++ ● Java has Reflection API ● Perl has Moose

Slide 24

Slide 24 text

Why do we need a MOP?

Slide 25

Slide 25 text

Testing

Slide 26

Slide 26 text

Testing ● I work at booking.com ● Our website is moving very fast ● Many rollouts in a day

Slide 27

Slide 27 text

Testing ● We don't test everything ● At one point, rollouts became hard ● Some things need to be tested manually

Slide 28

Slide 28 text

Testing package Web::Handler { has 'search' => ( url => '/search', #... ); has 'hotel' => ( url => '/hotel', #... ); # ... }

Slide 29

Slide 29 text

Testing package Web::Handler { has 'search' => ( url => '/search', #... ); has 'hotel' => ( url => '/hotel', #... ); # ... }

Slide 30

Slide 30 text

Testing package Web::Handler { has 'search' => ( url => '/search', #... ); has 'hotel' => ( url => '/hotel', #... ); # ... }

Slide 31

Slide 31 text

Testing ● Give me all the attributes of Web::Handler. ● Run tests for all the attributes.

Slide 32

Slide 32 text

Testing # This is pseudocode, don't expect this # to compile my $attr = Web::Handler->meta->get_attributes_list; foreach my $a ( @$attr ) { next unless $a->attribute_exists('url'); my $url = $a->get_attribute('url'); die “test fails...\n” if( !LWP::Simple::get($url) ); }

Slide 33

Slide 33 text

Testing # This is pseudocode, don't expect this # to compile my $attr = Web::Handler->meta->get_attributes_list; foreach my $a ( @$attr ) { next unless $a->attribute_exists('url'); my $url = $a->get_attribute('url'); die “test fails...\n” if( !LWP::Simple::get($url) ); }

Slide 34

Slide 34 text

Testing # don't expect this to compile my $attr = Web::Handler->meta->get_attributes_list; foreach my $a ( @$attr ) { next unless $a->attribute_exists('url'); my $url = $a->get_attribute('url'); die “test fails...\n” if( !LWP::Simple::get($url) ); }

Slide 35

Slide 35 text

Testing # don't expect this to compile my $attr = Web::Handler->meta->get_attributes_list; foreach my $a ( @$attr ) { next unless $a->attribute_exists('url'); my $url = $a->get_attribute('url'); die “test fails...\n” if( !LWP::Simple::get($url) ); }

Slide 36

Slide 36 text

Testing # don't expect this to compile my $attr = Web::Handler->meta->get_attributes_list; foreach my $a ( @$attr ) { next unless $a->attribute_exists('url'); my $url = $a->get_attribute('url'); die “test fails...\n” if( !LWP::Simple::get($url) ); }

Slide 37

Slide 37 text

Testing # don't expect this to compile my $attr = Web::Handler->meta->get_attributes_list; foreach my $a ( @$attr ) { next unless $a->attribute_exists('url'); my $url = $a->get_attribute('url'); die “test fails...\n” if( !LWP::Simple::get($url) ); }

Slide 38

Slide 38 text

Object Relational Mapping (ORM)

Slide 39

Slide 39 text

ORM my $create_table_statement =<

Slide 40

Slide 40 text

ORM my $sql_parser = SQL::Parser->new( $create_table_statement ); my $class_name = $sql_parser->table_name; my $c = Moose::Meta::Class->create( $class_name );

Slide 41

Slide 41 text

ORM my $sql_parser = SQL::Parser->new( $create_table_statement ); my $class_name = $sql_parser->table_name; my $c = Moose::Meta::Class->create( $class_name );

Slide 42

Slide 42 text

ORM my $sql_parser = SQL::Parser->new( $create_table_statement ); my $class_name = $sql_parser->table_name; my $c = Moose::Meta::Class->create( $class_name );

Slide 43

Slide 43 text

ORM my $sql_parser = SQL::Parser->new( $create_table_statement ); my $class_name = $sql_parser->table_name; my $c = Moose::Meta::Class->create( $class_name );

Slide 44

Slide 44 text

ORM foreach my $f ( $sql_parser->fields ) { my $tc = find_type_constraint( $f->type ); $c->add_attribute( Moose::Meta::Attribute->new( $f->name, isa => $tc, reader => 'get_' . $f->name, writer => 'set_' . $f->name, ); ); }

Slide 45

Slide 45 text

ORM foreach my $f ( $sql_parser->fields ) { my $tc = find_type_constraint( $f->type ); $c->add_attribute( Moose::Meta::Attribute->new( $f->name, isa => $tc, reader => 'get_' . $f->name, writer => 'set_' . $f->name, ); ); }

Slide 46

Slide 46 text

ORM foreach my $f ( $sql_parser->fields ) { my $tc = find_type_constraint( $f->type ); $c->add_attribute( Moose::Meta::Attribute->new( $f->name, isa => $tc, reader => 'get_' . $f->name, writer => 'set_' . $f->name, ); ); }

Slide 47

Slide 47 text

ORM foreach my $f ( $sql_parser->fields ) { my $tc = find_type_constraint( $f->type ); $c->add_attribute( Moose::Meta::Attribute->new( $f->name, isa => $tc, reader => 'get_' . $f->name, writer => 'set_' . $f->name, ); ); }

Slide 48

Slide 48 text

ORM foreach my $f ( $sql_parser->fields ) { my $tc = find_type_constraint( $f->type ); $c->add_attribute( Moose::Meta::Attribute->new( $f->name, isa => $tc, reader => 'get_' . $f->name, writer => 'set_' . $f->name, ); ); }

Slide 49

Slide 49 text

ORM foreach my $f ( $sql_parser->fields ) { my $tc = find_type_constraint( $f->type ); $c->add_attribute( Moose::Meta::Attribute->new( $f->name, isa => $tc, reader => 'get_' . $f->name, writer => 'set_' . $f->name, ); ); }

Slide 50

Slide 50 text

ORM foreach my $f ( $sql_parser->fields ) { my $tc = find_type_constraint( $f->type ); $c->add_attribute( Moose::Meta::Attribute->new( $f->name, isa => $tc, reader => 'get_' . $f->name, writer => 'set_' . $f->name, ); ); }

Slide 51

Slide 51 text

ORM package SomeDB::Class::Thing; ..... sub retrieve { .... } sub search_where {....} 1; $c->set_superclass( 'SomeDB::Class::Thing' );

Slide 52

Slide 52 text

ORM # return me the hotel with id 123 my $h = Hotel->retrieve( 123 ); my $hotel_name = $h->name; $h->set_name( 'asdfasdf' );

Slide 53

Slide 53 text

ORM # return me the hotel with id 123 my $h = Hotel->retrieve( 123 ); # return me the hotel id 123 my $hotel_name = $h->name; $h->set_name( 'asdfasdf' );

Slide 54

Slide 54 text

ORM # return me the hotel with id 123 my $h = Hotel->retrieve( 123 ); # return me the hotel id 123 my $hotel_name = $h->name; $h->set_name( 'asdfasdf' );

Slide 55

Slide 55 text

Implementing MOP in Perl

Slide 56

Slide 56 text

Creating a class at runtime ● Perl class is a package ● Every package has a symbol table

Slide 57

Slide 57 text

Symbol table ● Hash of subroutines/variables defined in a package ● package name with two colons appended $Rectangle::

Slide 58

Slide 58 text

Symbol table ● Hash of subroutines/variables defined in a package ● package name with two colons appended $Rectangle::

Slide 59

Slide 59 text

package Metaclass; sub create_class { my ($self, %options) = @_; my $class = $options{ package }; my $methods = $options{ methods }; while( my ($method, $body) = each( %$methods ) ) { no strict 'refs'; *{ "${class}::$method" } = $body; } # end while loop } 1;

Slide 60

Slide 60 text

package Metaclass; sub create_class { my ($self, %options) = @_; my $class = $options{ package }; my $methods = $options{ methods }; while( my ($method, $body) = each( %$methods ) ) { no strict 'refs'; *{ "${class}::$method" } = $body; } # end while loop } 1;

Slide 61

Slide 61 text

package Metaclass; sub create_class { my ($self, %options) = @_; my $class = $options{ package }; my $methods = $options{ methods }; while( my ($method, $body) = each( %$methods ) ) { no strict 'refs'; *{ "${class}::$method" } = $body; } # end while loop } 1;

Slide 62

Slide 62 text

package Metaclass; sub create_class { my ($self, %options) = @_; my $class = $options{ package }; my $methods = $options{ methods }; while( my ($method, $body) = each( %$methods ) ) { no strict 'refs'; *{ "${class}::$method" } = $body; } # end while loop } 1;

Slide 63

Slide 63 text

package Metaclass; sub create_class { my ($self, %options) = @_; my $class = $options{ package }; my $methods = $options{ methods }; while( my ($method, $body) = each( %$methods ) ) { no strict 'refs'; *{ "${class}::$method" } = $body; } # end while loop } 1;

Slide 64

Slide 64 text

package Metaclass; sub create_class { my ($self, %options) = @_; my $class = $options{ package }; my $methods = $options{ methods }; while( my ($method, $body) = each( %$methods ) ) { no strict 'refs'; *{ "${class}::$method" } = $body; } # end while loop } 1;

Slide 65

Slide 65 text

package Metaclass; sub create_class { my ($self, %options) = @_; my $class = $options{ package }; my $methods = $options{ methods }; while( my ($method, $body) = each( %$methods ) ) { no strict 'refs'; *{ "${class}::$method" } = $body; } # end while loop } 1;

Slide 66

Slide 66 text

package Metaclass; sub create_class { my ($self, %options) = @_; my $class = $options{ package }; my $methods = $options{ methods }; while( my ($method, $body) = each( %$methods ) ) { no strict 'refs'; *{ "${class}::$method" } = $body; } # end while loop } 1;

Slide 67

Slide 67 text

Metaclass->create_class( package => 'Rectangle', methods => { new => sub { my ($self) = shift; my $attributes = { @_ }; return bless $attributes, $self; }, } ); Rectangle->new( height => 10, Width => 20 );

Slide 68

Slide 68 text

Metaclass->create_class( package => 'Rectangle', methods => { new => sub { my ($self) = shift; my $attributes = { @_ }; return bless $attributes, $self; }, } ); Rectangle->new( height => 10, Width => 20 );

Slide 69

Slide 69 text

Metaclass->create_class( package => 'Rectangle', methods => { new => sub { my ($self) = shift; my $attributes = { @_ }; return bless $attributes, $self; }, } ); Rectangle->new( height => 10, Width => 20 );

Slide 70

Slide 70 text

Metaclass->create_class( package => 'Rectangle', methods => { new => sub { my ($self) = shift; my $attributes = { @_ }; return bless $attributes, $self; }, } ); Rectangle->new( height => 10, Width => 20 );

Slide 71

Slide 71 text

Metaclass->create_class( package => 'Rectangle', methods => { new => sub { my ($self) = shift; my $attributes = { @_ }; return bless $attributes, $self; }, } ); Rectangle->new( height => 10, Width => 20 );

Slide 72

Slide 72 text

sub create_class { my ($self, %options) = @_; my $class = $options{ package }; $options{ methods }->{ meta } = \&get_meta; my $methods = $options{ methods }; while( my ($method, $body) = each( %$methods ) ) { no strict 'refs'; *{ "${class}::$method" } = $body; } # end while loop }

Slide 73

Slide 73 text

my %meta_to_class; sub get_meta { my $class = shift; Metaclass->get_metaclass( $class ); }; sub get_metaclass { my $class = shift; return bless $meta_to_class{ $_[ 0 ] }, $class; }

Slide 74

Slide 74 text

my %meta_to_class; sub get_meta { my $class = shift; Metaclass->get_metaclass( $class ); }; sub get_metaclass { my $class = shift; return bless $meta_to_class{ $_[ 0 ] }, $class; }

Slide 75

Slide 75 text

my %meta_to_class; sub get_meta { my $class = shift; Metaclass->get_metaclass( $class ); }; sub get_metaclass { my $class = shift; return bless $meta_to_class{ $_[ 0 ] }, $class; }

Slide 76

Slide 76 text

my %meta_to_class; sub get_meta { my $class = shift; Metaclass->get_metaclass( $class ); }; sub get_metaclass { my $class = shift; return bless $meta_to_class{ $_[ 0 ] }, $class; }

Slide 77

Slide 77 text

my %meta_to_class; sub get_meta { my $class = shift; Metaclass->get_metaclass( $class ); }; sub get_metaclass { my $class = shift; return bless $meta_to_class{ $_[ 0 ] }, $class; }

Slide 78

Slide 78 text

my %meta_to_class; sub get_meta { my $class = shift; Metaclass->get_metaclass( $class ); }; sub get_metaclass { my $class = shift; return bless $meta_to_class{ $_[ 0 ] }, $class; }

Slide 79

Slide 79 text

my %meta_to_class; sub get_meta { my $class = shift; Metaclass->get_metaclass( $class ); }; sub get_metaclass { my $class = shift; return bless $meta_to_class{ $_[ 0 ] }, $class; }

Slide 80

Slide 80 text

sub create_class { my ($self, %options) = @_; my $class = $options{ package }; $options{ methods }->{ meta } = \&get_meta; my $methods = $options{ methods }; no strict 'refs'; while( my ($method, $body) = each( %$methods ) ) { *{ "${class}::$method" } = $body; } # end while loop use strict; set_metaclass( $class, \%options ); }

Slide 81

Slide 81 text

my %meta_to_class; sub get_meta { my $class = shift; Metaclass->get_metaclass( $class ); }; sub get_metaclass { my $class = shift; return bless $meta_to_class{ $_[ 0 ] }, $class; } sub set_metaclass { $meta_to_class{ $_[ 0 ] } = $_[ 1 ]; }

Slide 82

Slide 82 text

my %meta_to_class; sub get_meta { my $class = shift; Metaclass->get_metaclass( $class ); }; sub get_metaclass { my $class = shift; return bless $meta_to_class{ $_[ 0 ] }, $class; } sub set_metaclass { $meta_to_class{ $_[ 0 ] } = $_[ 1 ]; }

Slide 83

Slide 83 text

Introspection Metaclass->create_class( package => 'Rectangle', methods => { new => sub { my ($self) = shift; my $attributes = { @_ }; return bless $attributes, $self; }, }, ); print Dumper( Rectangle->meta );

Slide 84

Slide 84 text

bless({ 'package' => 'Rectangle', 'methods' => { 'meta' => sub { "DUMMY" }, 'new' => sub { "DUMMY" } } }, 'Metaclass' );

Slide 85

Slide 85 text

bless({ 'package' => 'Rectangle', 'methods' => { 'meta' => sub { "DUMMY" }, 'new' => sub { "DUMMY" } } }, 'Metaclass' );

Slide 86

Slide 86 text

Inheritance ● Every package's symbol table has an array named ISA ● @PackageName::ISA

Slide 87

Slide 87 text

Inheritance if( $options{ superclasses } && @{$options{ superclasses }} ) { @{"${class}::ISA"} = @{$options{ superclasses }} }

Slide 88

Slide 88 text

Inheritance if( $options{ superclasses } && @{$options{ superclasses }} ) { @{"${class}::ISA"} = @{$options{ superclasses }}; }

Slide 89

Slide 89 text

Metaclass->create_class( package => 'ColoredRectangle', superclasses => [ 'Rectangle' ], );

Slide 90

Slide 90 text

Metaclass->create_class( package => 'ColoredRectangle', superclasses => [ 'Rectangle' ], );

Slide 91

Slide 91 text

And it works, I can do ColoredRectangle->new();

Slide 92

Slide 92 text

But please don't try aforementioned things

Slide 93

Slide 93 text

It's incomplete & may be fragile

Slide 94

Slide 94 text

But why?

Slide 95

Slide 95 text

“Manipulating stashes (Perl's symbol tables) is occasionally necessary, but incredibly messy, and easy to get wrong. This module hides all of that behind a simple API.” `man Package::Stash`

Slide 96

Slide 96 text

But why? ● use Package::Stash; ● use Symbol::Table;

Slide 97

Slide 97 text

But why? ● Metaclass.pm is very basic ● But actually Metaclasses are not so simple ● Look at Moose

Slide 98

Slide 98 text

Moose ● Metaclasses for attributes ● Metaclasses for methods

Slide 99

Slide 99 text

Inheritance & metaclass compatibility ● A has a method i-foo – Calls c-bar of MetaA ● B inherits from A – B has i-foo ● MetaB may not have c-bar

Slide 100

Slide 100 text

Inheritance & metaclass compatibility package MetaA; .... sub c_bar { print "in c_bar\n"; } 1;

Slide 101

Slide 101 text

Inheritance & metaclass compatibility MetaA->create_class( package => 'A', methods => { new => sub { my ($self) = shift; my $attributes = { @_ }; return bless $attributes, $self; }, i_foo => sub { my ($self) = shift; my $meta = $self->meta; $meta->c_bar; }, }, ); A->i_foo();

Slide 102

Slide 102 text

Inheritance & metaclass incompatibility MetaB->create_class( package => 'B', methods => { new => sub { my ($self) = shift; my $attributes = { @_ }; return bless $attributes, $self; }, }, superclasses => [ 'A' ], ); B->i_foo;

Slide 103

Slide 103 text

Inheritance & metaclass incompatibility Can't locate object method "c_bar" via package "MetaB" at test.pl line 24.

Slide 104

Slide 104 text

Inheritance & metaclass incompatibility i_foo => sub { my ($self) = shift; my $meta = $self->meta; $meta->c_bar; },

Slide 105

Slide 105 text

Inheritance & metaclass incompatibility package MetaB; .... # NO c_bar 1;

Slide 106

Slide 106 text

Inheritance & metaclass incompatibility ● MetaA has a method c-foo ● c-foo needs to call i- bar in A ● MetaB inherits from MetaA ● B has to has i-bar

Slide 107

Slide 107 text

Inheritance & metaclass incompatibility package MetaA; ..... sub c_foo { my ( $self, $child ) = @_; $child->i_bar; } 1;

Slide 108

Slide 108 text

Inheritance & metaclass incompatibility package MetaB; use strict; use warnings; use parent 'MetaA'; 1;

Slide 109

Slide 109 text

Inheritance & metaclass incompatibility MetaA->create_class( package => 'A', methods => { new => sub { my ($self) = shift; my $attributes = { @_ }; return bless $attributes, $self; }, i_bar => sub { print "in i_bar\n"; }, }, ); MetaA->c_foo( 'A' );

Slide 110

Slide 110 text

Inheritance & metaclass incompatibility MetaB->create_class( package => 'B', methods => { new => sub { my ($self) = shift; my $attributes = { @_ }; return bless $attributes, $self; }, # NO i_bar }, ); MetaB->c_foo( 'B' );

Slide 111

Slide 111 text

Inheritance & metaclass incompatibility Can't locate object method "i_bar" via package "B" at MetaA.pm line 16.

Slide 112

Slide 112 text

Inheritance & metaclass compatibility sub c_foo { my ( $self, $child ) = @_; $child->i_bar; }

Slide 113

Slide 113 text

Metaclass Incompatibility ● Various ways of dealing with this

Slide 114

Slide 114 text

Metaclass compatibility (Moose) ● Does parent & child metaclasses have any common ancestors? – If yes, then \o/ – else, die ● Moose::Exception::CannotFixMetaclassComp atibility

Slide 115

Slide 115 text

Mixins ● A class that contains a combination of methods from other classes ● 'Included' rather than 'inherited' ● Moose roles are similar to mixins

Slide 116

Slide 116 text

Rules of mixins-based inheritance ● Order of the mixins matter ● Mixins take precedence over non-mixins

Slide 117

Slide 117 text

Mixins-based inheritance

Slide 118

Slide 118 text

Mixins-based inheritance ● B => {M1.M2.A}

Slide 119

Slide 119 text

Rules of mixins-based inheritance ● Methods in M2 will take precedence over A ● Methods in M1 will take precedence over M2

Slide 120

Slide 120 text

Mixins-based inheritance ● C => { M3.B.M1.M2.A }

Slide 121

Slide 121 text

Rules of mixins-based inheritance ● Methods in B will take precedence over M1 ● Methods in M3 will take precedence over B

Slide 122

Slide 122 text

Moose provides a great MOP

Slide 123

Slide 123 text

Creating a class Moose::Meta::Class->create( 'Rectangle', attributes => { 'height' => { is => 'ro', isa => 'Int', }, ... }, );

Slide 124

Slide 124 text

Introspection ● For getting attributes: Rectangle->meta->get_attributes_list(); ● For getting methods: Rectangle->meta->get_methods_list(); ● For getting superclasses: Rectangle->meta->superclasses;

Slide 125

Slide 125 text

Introspection ● For getting attributes: Rectangle->meta->get_attributes_list(); ● For getting methods: Rectangle->meta->get_methods_list(); ● For getting superclasses: Rectangle->meta->superclasses;

Slide 126

Slide 126 text

Introspection ● For getting attributes: Rectangle->meta->get_attributes_list(); ● For getting methods: Rectangle->meta->get_methods_list(); ● For getting superclasses: Rectangle->meta->superclasses;

Slide 127

Slide 127 text

Introspection ● For getting attributes: Rectangle->meta->get_attributes_list(); ● For getting methods: Rectangle->meta->get_methods_list(); ● For getting superclasses: Rectangle->meta->superclasses;

Slide 128

Slide 128 text

Changing Class definition ● For adding a new attribute: Rectangle->meta->add_attribute(...); ● For adding a new method: Rectangle->meta->add_method(...);

Slide 129

Slide 129 text

Changing Class definition ● For adding a new attribute: Rectangle->meta->add_attribute(...); ● For adding a new method: Rectangle->meta->add_method(...);

Slide 130

Slide 130 text

Changing Class definition ● For adding a new attribute: Rectangle->meta->add_attribute(...); ● For adding a new method: Rectangle->meta->add_method(...);

Slide 131

Slide 131 text

Drawbacks of MOP ● Makes things slow ● While using Moose, don't forget to do: __PACKAGE__->meta->make_immutable; – It tells Moose that you are not going to change your class at runtime

Slide 132

Slide 132 text

Bibliography ● The Art of the Metaobject Protocol ● Metaclass Composition Using Mixin-Based Inheritance by Noury Bouraqadi ● Wikipedia ● Moose documentation ● And lots of other random resources on the internet ● Stevan Little's awesome brain :)

Slide 133

Slide 133 text

Thank you for your time

Slide 134

Slide 134 text

Questions?

Slide 135

Slide 135 text

● Slides: https://speakerdeck.com/upasana20/intro-to-mop-presented-a t-yapc-na ● Code examples: https://github.com/Sweet-kid/Intro-to-MOP-YAPC