Slide 1

Slide 1 text

Metaprogramming in Ruby Created By Kristen Mills

Slide 2

Slide 2 text

What is Metaprogramming?

Slide 3

Slide 3 text

The Basics

Slide 4

Slide 4 text

Symbols Kind of like strings Immutable Not garbage collected

Slide 5

Slide 5 text

Blocks That do...end thing or curly braces if on one line One of the 3 types of closures

Slide 6

Slide 6 text

Monkey Patching

Slide 7

Slide 7 text

Monkey Patching by example c l a s s S t r i n g d e f m y _ m e t h o d " m y _ m e t h o d i s a c o o l m e t h o d " e n d e n d ' a b c ' . m y _ m e t h o d # = > " m y _ m e t h o d i s a c o o l m e t h o d "

Slide 8

Slide 8 text

Refinements Allows you to monkey patch in a given scope

Slide 9

Slide 9 text

Aliasing method alias method_1, method_2 alias_method :method_1, :method_2

Slide 10

Slide 10 text

Defining Methods def method_name(params) define_method(name, &block) define_singleton_method(name, &block)

Slide 11

Slide 11 text

Instance Variables instance_variable_set(name, value) instance_variable_get(name)

Slide 12

Slide 12 text

attr_accessor d e f a t t r _ a c c e s s o r ( * a r g s ) a r g s . e a c h d o | a r g | d e f i n e _ m e t h o d ( a r g ) d o i n s t a n c e _ v a r i a b l e _ g e t ( : " @ # { a r g } " ) e n d d e f i n e _ m e t h o d ( : " # { a r g } = " ) d o | v a l u e | i n s t a n c e _ v a r i a b l e _ s e t ( : " @ # { a r g } " , v a l u e ) e n d e n d e n d

Slide 13

Slide 13 text

Eigenclasses!

Slide 14

Slide 14 text

Wait, where does that method go?

Slide 15

Slide 15 text

Accessing the Eigenclass e i g e n c l a s s = c l a s s < < o b j c l a s s < < a n _ o b j e c t # y o u r c o d e h e r e e n d

Slide 16

Slide 16 text

Before you ask Yes, eigenclasses have Eigenclasses

Slide 17

Slide 17 text

Calling Methods send(name, *args)

Slide 18

Slide 18 text

Removing Methods remove_method(name) undef_method(name)

Slide 19

Slide 19 text

Rails Black Magic (aka Method Missing)

Slide 20

Slide 20 text

Method Missing method_missing(method, *args, &block)

Slide 21

Slide 21 text

Domain Specific Languages

Slide 22

Slide 22 text

Evaluating Strings/Blocks eval(string) instance_eval(string) instance_eval(&block) instance_exec(*args, &block) yield(*args) call(*args)

Slide 23

Slide 23 text

Vending Machine f i n i t e i n i t i a l : : i d l e d o b e f o r e : i d l e d o @ c u r r e n t _ m o n e y = 0 e n d a f t e r : a c c e p t i n g d o p u t s " C u r r e n t a m o u n t i n m a c h i n e : $ % . 2 f " % @ c u r r e n t _ m o n e y e n d @ m o n e y . e a c h d o | e v e n t _ n a m e , a m o u n t | e v e n t : " i n s e r t _ # { e v e n t _ n a m e } " d o b e f o r e d o p u t s " A d d i n g # { e v e n t _ n a m e } " a d d _ m o n e y ( a m o u n t ) e n d g o f r o m : : i d l e , t o : : a c c e p t i n g g o f r o m : : a c c e p t i n g , t o : : a c c e p t i n g e n d e n d @ p r o d u c t s . e a c h d o | e v e n t _ n a m e , p r i c e | e v e n t : " b u y _ # { e v e n t _ n a m e } " d o b e f o r e { p u t s " B u y i n g # { e v e n t _ n a m e } " } g o f r o m : : a c c e p t i n g , t o : : v e n d i n g , i f : l a m b d a { @ c u r r e n t _ m o n e y > = p r i c e } a f t e r d o @ c u r r e n t _ m o n e y - = p r i c e e n d e n d e n d e v e n t : c o m p l e t e _ v e n d d o b e f o r e { p u t s " R e t u r n i n g $ % . 2 f t o t h e c u s t o m e r " % @ c u r r e n t _ m o n e y } g o f r o m : : v e n d i n g , t o : : i d l e e n d e v e n t : p r e s s _ c o i n _ r e t u r n d o

Slide 24

Slide 24 text

add_event d e f a d d _ e v e n t ( e v e n t _ n a m e , & b l o c k ) # S o m e o t h e r s t u f f h a p p e n s b e f o r e h e r e @ c l a s s . s e n d ( : d e f i n e _ m e t h o d , : " c a n _ # { e v e n t _ n a m e } ? " ) d o e v e n t . t r a n s i t i o n s . k e y ? c u r r e n t _ s t a t e . n a m e e n d @ c l a s s . s e n d ( : d e f i n e _ m e t h o d , : " # { e v e n t _ n a m e } " ) d o i f e v e n t . t r a n s i t i o n s . k e y ? c u r r e n t _ s t a t e . n a m e t r a n s i t i o n = e v e n t . t r a n s i t i o n s [ c u r r e n t _ s t a t e . n a m e ] u n l e s s t r a n s i t i o n . c o n d i t i o n . n i l ? o r s e l f . i n s t a n c e _ e x e c ( & t r a n s i t i o n . c o n d i t i o n ) r a i s e E r r o r . n e w ( ' D o e s n o t m e e t t h e t r a n s i t i o n c o n d i t i o n ' ) e n d n e w _ s t a t e = s t a t e s [ e v e n t . t r a n s i t i o n s [ c u r r e n t _ s t a t e . n a m e ] . t o ] e v e n t . c a l l b a c k s [ : b e f o r e ] . e a c h d o | c a l l b a c k | s e l f . i n s t a n c e _ e v a l & c a l l b a c k e n d # M o r e c a l l b a c k s h a p p e n h e r e @ c u r r e n t _ s t a t e = n e w _ s t a t e # M o r e C a l l b a c k s h a p p e h e r e e v e n t . c a l l b a c k s [ : a f t e r ] . e a c h d o | c a l l b a c k | s e l f . i n s t a n c e _ e v a l & c a l l b a c k e n d s e l f e l s e r a i s e E r r o r . n e w ' I n v a l i d T r a n s i t i o n ' e n d e n d e n d

Slide 25

Slide 25 text

Any Questions?

Slide 26

Slide 26 text

Thanks!