00:00:17.199
this is the first pre um talk after lunch so while you are guys are enjoying the breakdown of gluten in your
00:00:22.720
bloodstream i will be talking to you about practical metarogramming like to introduce myself
00:00:27.920
briefly my name is stephen harms i live in san francisco uh you can email me at that address or you can find me on
00:00:34.960
twitter or github on at that same address i'm also on google+ but i think
00:00:40.480
i may be the last person there so we'll see how that goes uh i love new orleans new orleans
00:00:47.120
is a town that means a lot to me i'm uh i was born in texas but i spent a number of my years growing up in slidell which
00:00:53.760
is just across i 10 over there um and for first- time visitors i highly recommend getting a sazzarak from the
00:01:00.239
place where it was invented the roosevelt hotel it's right around the corner you will not regret it it's
00:01:06.080
called a sazzarak it's a rye and it is delicious yeah um let me break this out
00:01:15.680
by saying i originally pitched this as a different talk uh we wrote it months ago and just like jim hayrick i found that
00:01:22.560
what i want to communicate to you has changed a little bit we've seen a number of interesting
00:01:27.840
developments in the ruby community over the last uh two months particularly around the conferences and what i've
00:01:34.079
seen a lot of uptake in is the conception of ruby as a message passing
00:01:40.799
programming language we're taking a lot of cues from small talk in that and as i thought about the message passing
00:01:47.680
behavior it seemed like a very good way for us to lend the perennial topic of metaroming in ruby so that's what i'm
00:01:55.360
going to be talking about practical metaroming as lensed through message
00:02:00.479
passing i don't know about you but i love the ruby rogues podcast i think they're a
00:02:06.640
source of great information but i'm about to totally ribb them or diss them or hate on them depending on your
00:02:13.800
dialect i think they give a very good example of why it's so hard to learn
00:02:19.000
metarogramming within the ruby community because they are proponents of impractical metaroming
00:02:26.480
if you listen to episode number 12 of the ruby rugs podcast they proceed to
00:02:31.760
use the first 10 minutes to try to define the word metarogramming and here's what they
00:02:36.959
cover in the first 10 minutes lisp hey that's great marshalling code closures
00:02:44.680
state code is data a um just quick hands up who knows what a stands for oh all
00:02:51.920
right you guys are geniuses all right um from a pedagogical point of view i' i'd
00:02:56.959
like that to occasionally be spelled out they do it in the liner notes but that's okay um they also talk about code
00:03:02.879
generation versus runtime behavior is that metaroming or is that not metaroming now if i were looking for the
00:03:09.599
simple definition of that word i might be a little bit confused at this
00:03:15.000
point jackie expresses bafflement like no other human except for maybe a slide
00:03:20.080
we'll see a little bit later um so james edward gray ii tries to
00:03:26.400
corral the discussion and says can we come up with a working definition of
00:03:31.640
metaroming and here are the answers that our esteemed guests give us it might be
00:03:37.120
an api for dynamic programming within the ruby language it might be programming other
00:03:43.120
people's programs someone cites giles balette who says that there's no such
00:03:48.239
thing as metaroming there is just programming typically zen kind of approach for enlightened masters of the
00:03:54.799
ruby community um another voice chimes in that it's things that treat code as data
00:04:02.319
and lastly it's anything that would blow the mind of a java
00:04:08.200
programmer now once you understand metaroming most of these are very very pathy and very very insightful however
00:04:15.120
if you're a new beginner coming to the mystery of meta programming maybe you've mastered deaf class module maybe you're
00:04:22.720
just basically getting your feet wet in the ruby language if you're just about to cross that threshold seeing these
00:04:28.479
definitions doesn't serve to really define what metaroming is so that's where practical metaroming
00:04:36.080
comes in and that's going to be the content of my talk today so here it is this is written by
00:04:42.160
ruby average joe me um i don't have a really cool twitter handle i don't have really stylish facial hair i'm just an
00:04:50.720
average ruby joe um the other thing is i'm going to focus on experiences not theory i will
00:04:56.880
not use terms like as i will not debate the merits of closures or blocks or procs instead what i'm going to do is
00:05:03.759
show that metaroming is core to the identity of ruby and you can actually do it with the
00:05:09.560
basic declarations that you already know and love even the ones that you learn from a basic ruby in 30 minutes
00:05:17.000
tutorial again we're going to build from basic ruby on up now you might be asking yourself why
00:05:23.759
do i need to learn meta programming with that greek prefix meta it sounds like it might be superolous or unnecessary
00:05:29.759
however this is very much not the case you really do need to understand meta programming because if you ever want to
00:05:35.360
contribute to ruby core or rails core you're going to find these techniques and patterns all over the place for
00:05:41.360
example in the exception to message mapper now this is a really funny bit of
00:05:46.960
meta programming if you look at it but if you don't understand what's going on here
00:05:53.199
you'll never be able to make a contribution this is one of the core pieces of irb so everyone uses it all
00:05:59.440
the time and if you don't understand what's going on here you won't understand how exceptions are passed within
00:06:04.520
irb and as i already said rails uses meta programming all over the place how else do we get like 93 frames of stack
00:06:12.240
every time an error blows the other thing is i'm kind of good lazy at least i hope i'm good lazy
00:06:18.960
i don't like to type a lot metarogramming allows you to scale up a little bit of logic to cover many many
00:06:24.880
cases and lastly some domains are very ambiguous and you can use metarogramming
00:06:31.039
to reflect the inherent ambiguity of the domain
00:06:36.840
period and lastly there are some pleasant surprises uh sometimes when you are metrogramming it turns out that the
00:06:42.560
code that you put in place is smarter than you thought it was and it yields interesting insights into the code
00:06:48.440
structure and the domain you're modeling so my goals today are to dispel the fud
00:06:54.800
around metarogramming you should metrogram boldly uh in short i want you to feel awesome using this
00:07:01.240
technique i will argue that metarogramming is just meta is just programming so i'll be stealing uh
00:07:07.199
giles's statement and i also want to introduce newcomers to four tiers of metaroming so that they understand the
00:07:14.560
path of leading from neoight to an experienced meta programmer
00:07:20.000
i'm also going to answer um a mandate or a request that came in the ruby rogues
00:07:25.360
podcast from uh james edward gray which is that at some point as a rubist you must understand the ancestor chain and
00:07:32.479
there's no better tool for exploring and understanding what the ancestor chain is doing than to understand meta
00:07:38.639
programming and lastly i'll show you a few real world examples of the benefits of
00:07:44.160
metaroming from a library i created that's used to model uh verb conjugation
00:07:49.680
obviously uh human linguistics is a highly ambiguous domain and metarogramming was the only way that i
00:07:55.360
could scale from one solitary developer to cover all the cases that were going
00:08:00.800
to surface so let's talk a little bit about uh gray's mandate as i'm calling it which
00:08:07.840
is that the method call system is really important and i'm quoting here and you have to get your head around it at some
00:08:13.599
point about how it does these lookups method call system is a straight line with stops along the way once you get
00:08:20.000
the hang of it you realize you can put a module at any point on that line and it's absolutely critical to understand
00:08:26.240
this chain so that you understand the rules so that you can break them with metarogramming so we'll be using this
00:08:32.800
mandate as a guideline as we cover the basic cases of metaroming so for the beginners i'm
00:08:39.680
going to give this uh argument that metaroming is programming and also i'm
00:08:44.800
going to help you feel more confident but for the experienced meta programmers in the audience i'm going to show you
00:08:49.920
some uh rather woolly stuff that i do in my own library so i hope to cover both
00:08:55.440
the uh beginner spectrum as well as the advanced spectrum so if that sounds good to you uh please
00:09:03.200
stay where you're seated but if it doesn't sound good to you there's two other tracks that i'd really really like for you to enjoy i have absolutely no
00:09:10.880
compunction about any of you standing up right now and leaving okay well i won't need this one
00:09:17.120
after all so let's talk about our first
00:09:22.720
contact with metaroming like jean luke and the borg queen here so seriously
00:09:28.399
what is metaroming it took the ruby rogues mine's far greater and more powerful than mine a whole 10 minutes to
00:09:34.240
not answer this question but i will attempt to give it to you uh straight and short my definition is this
00:09:41.760
metarrogramming is writing code that redirects past messages at runtime and i
00:09:47.839
have to say that this idea came to me while in constantine's talk if he's around here somewhere um but any case or
00:09:54.880
alternatively metarogramming is um altering the structures that answer those messages at
00:10:03.880
runtime and that was just said by me some dude but here's the question you might
00:10:09.440
be saying well isn't handling messages just regular programming and my argument
00:10:14.880
is yes and that is exactly why metarogramming is in fact just programming and we can demonstrate this
00:10:21.279
with very very simple tools let's see it in action so i'm gonna write a little bit of code
00:10:28.000
here using cat and redirect which is the way all real unix hackers do it um we echo excuse me i echoed i'll
00:10:36.399
cat later um so we echo a statement to puts the ancestor chain of self.class
00:10:43.519
and so that's going to to by default be the main object of a ruby program and then we're going to say that we want to
00:10:49.440
execute the method fraate now when we execute what you see here is the
00:10:55.279
ancestor chain starting at object moving to kernel and coming up to basic object uh for the record i am using 1.9 um in
00:11:03.440
other early rubies you wouldn't see basic object at the top and look here it
00:11:08.720
failed and the error message is quite handy and it says it failed because undefined local or var variable or
00:11:14.880
method uh fraudnikate was called now i think most of us can debug this just
00:11:20.160
just on site um the message failed because a message was passed that ruby
00:11:25.920
didn't know anything about right jackie chan george w bush same guy
00:11:32.959
ever seen him in the same place maybe so what do we do how do we
00:11:39.040
redirect this message how do we handle this message um does anybody want to say how they would handle it
00:11:48.480
you know you guys sometimes how about deaf deaf is a good
00:11:55.120
way to catch a message and it's the first thing you learned in ruby so here we are using cat so i def
00:12:04.360
fronicate puts fra and then i use that same bit of code we just saw to do the
00:12:10.480
exact same thing we see the same ancestor tree except and this time when we pass that message it's responded to
00:12:17.600
and the result comes back in so there we are metrogramming by my
00:12:23.440
definition we've just proceeded to catch a message that was passed now being programmers we want to
00:12:29.839
make things nice and neat so we don't want to just put a bunch of deaf statements so a logical step forward would be to put it into a class in this
00:12:36.959
time we put it in fro and this makes our ancestor chain grow by a depth of one so
00:12:44.880
now we have a fro at the base that bubbles up to object kernel and then basic
00:12:50.600
object we can get a little jiggy with it we can put it in a module instead interesting little thing to note
00:12:57.120
and this is kind of why modules are magic notice the ancestor chain here is of a depth of one it doesn't go up any
00:13:04.440
further this is part of the magic of why a mixin works but again we've put frognicate up at the
00:13:10.839
top and so we get a response as we expected we can get a little more crazy
00:13:17.519
by using the ruby standard of embedding the module or excuse me by embedding the method into a module and then embedding
00:13:24.399
the module into a class or known as the mix-in pattern so what we have here is
00:13:31.040
fro mod is brought into class fro and what we notice is that the ancestor chain is now a depth of two we have fro
00:13:38.320
at the base which wears fro mod almost almost as a mantle and then it continues
00:13:44.480
up that ancestor chain that we'd seen previously now we can also have a little
00:13:51.040
bit more fun on this by we can we can block the existence of one method by the
00:13:57.040
order in which it's mixed in into the class in this case we first mix in from mod which returns this and then we mix
00:14:04.480
in from mod 2 which returns this upon our execution we notice that the
00:14:09.760
behavior is the fronicate method as defined by fra mod 2 so the order in
00:14:15.839
which you include because ruby is an interpreted language will change the
00:14:21.160
behavior at runtime consequently we can change behavior of
00:14:27.279
the runtime by putting in something like this here's a simple random decision
00:14:32.639
tree if the rand is less than 0.5 include it in order one order two and if
00:14:38.399
it's the uh the alternate case include it in reverse order as a result the
00:14:43.839
ancestor chain looks like this sometimes about half the time and it looks like
00:14:49.040
this the other half of the time so what i would like to contend is that
00:14:54.160
i've just demonstrated that you can change the runtime behavior by changing the methods included at runtime that is
00:15:03.040
the definition of meta programming i've provided and not used any of the fancy methods that you um threw out at me
00:15:09.519
earlier on we don't have to use method missing we're not using class eval or instance eval metarrogramming is such a
00:15:15.839
fundamental core part of the way ruby is conceived you've been metrogramming all
00:15:21.120
along and you just didn't notice it
00:15:26.199
so that's a fact you are metrogrammers so what i would like to
00:15:33.600
continue on with is the supposition that you either need to accept that meta programming is easier than you thought
00:15:39.760
or that the difference is unimportant this is the first goal i brought up so i hope i've convinced you that the
00:15:45.760
difference between metaroming and programming is unimportant now that said it is useful
00:15:53.839
to talk about metaroming in terms of a style uh a certain way of editing and extending things with a certain set of
00:16:00.320
ruby constructs but ne but i would like mentally when you hear me say the word metaroming from now on put ironic
00:16:06.720
hipster quotes around it and realize that i'm talking about a stylistic thing versus a fundamental
00:16:13.279
behavioral difference i'm now going to move on to giving you what i consider to be four
00:16:19.440
tiers of um growth in steps and service towards your metarogramming paladinhood
00:16:27.040
so this is ideal for the beginner or intermediate crew who are looking to understand metarogramming in a more deep
00:16:36.120
fashion i'm going to take the names for these idioms or spells as paulo parata
00:16:42.240
calls them um because i think as a community we need to standardize on names this is part of the beauty of
00:16:47.279
design patterns it gives us a way for communicating and interfacing with one another and knowing which e what each
00:16:52.959
other are talking about quickly paulo has put all the spells kindly online so if you would like to look at
00:16:58.959
the spells there they are um the they're all spelled out in greater depth in the meta programming ruby by pragmatic
00:17:06.439
press so i would like to talk about the metarogramming prerequisites i've already introduced those just now basic
00:17:13.520
method manipulation creation by defaf basic class definition the class keyword
00:17:19.520
basic module definition the module keyword and lastly the mix-in pattern
00:17:27.400
fortunately these prerequisites are also the prerequisites required to do anything in ruby so it turns out you are
00:17:33.520
already at a already have a leg up the next section of metaroming
00:17:40.000
techniques i'd like to bring out are ones that center on advanced method redirection so basic method redirection
00:17:46.799
would be using deaf advanced method redirection is something like these um
00:17:52.160
the first would be the kernel method the monkey patch the adder methods and then the alias macro given that these are
00:18:00.240
fundamental and i want to communicate to the beginners in the audience i'm going to talk about these briefly and actually
00:18:05.440
show code samples so the open class we all know that in ruby we can open up a class at
00:18:12.000
runtime and tack on methods to the class so in this case i've added the method hop like a frog um in honor of iggy pop
00:18:21.600
um to the class string and that allows us to execute hop like a frog on any given string and get the result
00:18:28.840
sprawing i got to be honest the first time i heard this at a ruby conference i was kind of floored because it opened up
00:18:35.280
the mental dialogue in my head that without a compiler a class is basically
00:18:40.559
a namespace think about
00:18:45.600
additionally we have the kernel method whereby we can add effectively new keywords to our ruby runtime in this
00:18:52.160
case we add the keyword or method mick hobo which returns yehaw and here it is
00:19:00.120
demonstrated also and this is very familiar from with the pickax book is the ability to use the adder methods to
00:19:06.640
add uh getter and uh setter functions at runtime so here we go we
00:19:13.679
say we're going to add secret word we take create an instance of demo here and
00:19:19.440
then we have the setter so we set it to king hobo and we have the getter for
00:19:24.960
secret word we can also check that uh response is as predicted by using the
00:19:30.240
respond to method and lastly here's the one that falls in
00:19:35.520
that category of blow java programmer's minds is that we can add a specific method onto a specific instance of a
00:19:42.520
class in this case we create an instance of cake we add a method to it called birthday and here we see it working if i
00:19:50.400
created a new cake in this case zabu zabu does not have the decorate method
00:19:55.600
unlike uh which one was that unlike birthday up here
00:20:02.320
so i think most people once you get exposed to these first several methods
00:20:07.520
we kind of feel awesome i mean ruby's kind of awesome there aren't many languages that can do this i mean
00:20:14.559
there's some things that are more awesome like a lion riding horse that's much more awesome but that's still
00:20:19.840
pretty awesome what we've just seen but the trouble is is that with these tools i think a lot of us ruby
00:20:26.160
programmers who've tried this out a little bit can see that this might be the beginning of a maze of madness and
00:20:32.559
to this extent there comes in a lot of fear and uncertainty and doubt about whether or not we should be metroming at
00:20:38.320
all by my argument you've already been metrogramming so there's nothing to fear but you will occasionally hear voices
00:20:44.960
like the following from tim connor now to be fair uh tim really doesn't believe
00:20:50.880
this point of view as strongly as it's stated here in text but there is the sense that when neopightes begin
00:20:57.039
metaroming they often paint themselves into a corner or paint the code into a corner so so it's a real pain to
00:21:03.039
maintain later on contra-wise we have paulo now i sent
00:21:08.559
paulo the quoted verbatim text of what tim said and paulo's attitude was much more pragmatic which is that if we're
00:21:14.559
going to give people powerful tools they need to understand that they are powerful tools and they need to
00:21:19.919
understand how to use them i like to call this the table saw metaphor or the teenager metaphor
00:21:27.760
sometimes teenagers they have a whole lot of free will they have uh some
00:21:32.880
interesting ideas and occasionally they use those ideas to get up to mad cap hilarity like feathered
00:21:39.960
bangs but other times with proper guidance we have teens that exemplify pure brilliance like daniel son
00:21:50.440
here and we can always look to our mentors for proper advice on this like daniel's son who was so wise he looked
00:21:56.720
towards the wisdom of mr from yagi who reminds us that if our root is strong the tree will survive well in our case
00:22:03.440
we have a strong root we understand the ancestor chain we have a strong root we understand that we've been metrogramming
00:22:10.240
all along and as a result we have the tools to understand whether or not we're introducing needless complexity and we
00:22:17.200
also have the tools to figure out how to debug our way out of the corner so with that i want to encourage you experiment
00:22:23.600
with metaroming because you have absolutely nothing to fear your natural question will be how will
00:22:30.159
you know you're ready to move on beyond the basic tools that we've provided man pastels are great weren't
00:22:39.000
they i like this sample of code if you can scan this code and you can come to
00:22:44.080
the understanding of why all these methods are structurally identical you're ready to move on
00:22:50.480
and i don't i don't mean this to say this is like a merit badge test but if you feel comfortable looking at something like this and you understand
00:22:57.200
what's going on with the singleton class you understand what the embedding is doing then you're probably ready to
00:23:04.720
implement meta programming and the large
00:23:15.960
scale but this will be available uh online for you to consult later if you're still
00:23:22.000
puzzling it through but we're now going to move out of that
00:23:28.320
danger area and into the areas of idioms that are expected of competent meta
00:23:33.679
programmers what i call tier 2 are idioms which tend to center on taking
00:23:40.000
control out of ruby's hands for the handling and parsing of past messages so
00:23:45.760
you're saying ruby i want you to back off because i want to take a little bit more responsibility so this would be the
00:23:53.320
send method uh using method missing which everyone likes to hold up as their favorite bit
00:23:59.200
of metaroming uh the ghost method which is you send a message to something intentionally
00:24:06.240
knowing that the method is not defined there specifically so that you can trigger method missing so that you can
00:24:11.360
handle um the failed message at runtime or
00:24:17.120
lastly the around alias which is a sort of a hybrid of the monkey patch or open class which is you intercept a called
00:24:24.320
method but you still keep a reference to the original method so you can do some pre-processing or some post-processing
00:24:31.360
on the value that's coming in or going out now i'm not going to show code
00:24:36.720
samples of that because in the more advanced section which we're about to move into i will actually show those
00:24:42.799
techniques in actual use the final tier of metaroming tends to be
00:24:50.000
those which are around the dynamic generation and inclusion of modules that is to say you're going to create ways of
00:24:56.400
handling messages at runtime and you're going to bundle them in dynamically created
00:25:02.320
um and dynamically created black boxes which you will include at an arbitrarily
00:25:08.080
chosen point on the ancestor chain and lastly come the real power
00:25:14.080
tools um the absolute table saws which are class eval and instance eval at which point you can open up the guts of
00:25:20.480
a class and change its behavior at runtime obviously the most powerful the most invasive it breaks encapsulation
00:25:27.760
but sometimes you may feel the need to use this technique so one last word from mom and
00:25:33.440
dad is that most advanced techniques are fancy syntax for the basic techniques
00:25:38.720
everything you do with define underscore method you could have just done with deaf barring certain cases so always
00:25:44.720
keep in mind that these fancy syntaxes that you learn later on in your career of as a meta programmer are sometimes
00:25:51.360
just needless noise sometimes it's better just to go with the default constructs that the ruby language
00:25:58.360
provides and lastly uh the uncle ben's axiom which is not about rice but it's about toby magguire which is with great
00:26:06.080
power comes great responsibility so i'm going to talk about a particular
00:26:11.120
pet project of mine that has covered i think three time zones and three different ruby communities uh this was
00:26:17.600
actually started at lonear ruby conf 2 and has persisted across hack nights in
00:26:22.720
san francisco uh late night hack sessions in austin and uh pretty much everywhere in between because it's uh an
00:26:29.520
insane passion but what can i say it is definitely one of those worthless things
00:26:35.120
of questionable value that's solely driven by my passion and zeal for a 2500
00:26:40.480
year old dead language i'm glad i'm with a bunch of
00:26:46.120
nerds so i'm going to give you all you need to know about latin in four bullet points okay so brace yourself i'm going
00:26:52.320
to try to keep this short uh anybody speak a romance language spanish french
00:26:57.360
italian okay you guys are going to be a step ahead all right a verb in latin is
00:27:02.720
defined by these four parts good so far all
00:27:08.120
right we can refer to a unique result of this verb's
00:27:13.640
behavior we can call that unique result a conjugation as a result of passing these
00:27:20.240
five parameters we earn the singular result
00:27:25.440
of this guy cool five parameters one result that's the fully qualified domain
00:27:31.039
if you will that's the fully qualified specifier now i also wanted to include
00:27:38.080
the capability to flexibly respond in the case that the
00:27:43.720
specification occurs without all five specifiers so what if we left number off
00:27:49.360
i still want to get a useful result based on this what i left what if i left number and person off i still want to
00:27:55.600
get a useful result based on those three components so i need flexibility both in
00:28:01.600
terms of exact specification as well as more collective grouping
00:28:07.640
specifications okay and here's a quick graphic version of that which is that if i say first person i want two results if
00:28:14.399
i say singular number i want three or plural i want three but if i want the intersection of those two i just want a
00:28:20.880
single result that's all the latin you need to know to understand my insanity
00:28:26.080
so like any good programmer as i was learning latin i couldn't help but
00:28:31.760
notice the programmatic constructs that were inside of it noticing that conjugation is basically uh a use of
00:28:38.080
innumerable uh map and i just kind of sat there thinking what if i were to
00:28:43.120
start modeling verb conjugation in latin via ruby okay so i'd need six results
00:28:49.200
that means i need to find six methods uh for six tenses for two voices oh wait
00:28:55.120
there's another mood too and it has four tenses of its own uh that means there's about 160 unique vectors for every verb
00:29:02.000
and there's five of those thousand verbs possibly thousands of decisions uh
00:29:09.200
that was going to suck so i rolled the saving
00:29:16.120
throw natural
00:29:21.320
20 nerds but thankfully metarogramming
00:29:28.559
allowed me to scale up to comp to comprehend the potential thousands of possible cases by just providing a very
00:29:36.240
few number of methods about maybe two dozen uh or 26 i'm not sure how
00:29:42.240
understood that is amongst others so let's def let's stuff that
00:29:48.320
logic that intersection logic within a class called tense block so check out what we can
00:29:55.159
do given a tense block we could say second person get two results say plural
00:30:00.640
number get three results specify those two components get a singular result and
00:30:07.440
specify those two components in reverse order and still get the useful result so
00:30:13.600
imagine what would have had to happen if i coded all those methods out i don't do that instead i use the power of method
00:30:19.840
missing built into this class here it is i interrogate the class
00:30:26.399
and say do you have anything any methods that contain these words and for every
00:30:32.480
word i would like you to push that to an array and return the array value so if
00:30:37.600
you fully specify there's only one method that matches one result if you leave off one of the components say
00:30:43.919
first person or singular number three match and you might wind up getting
00:30:49.200
these collections back if you'd like to consult that further please feel free to consult the
00:30:54.679
source but my point being is that i was able to cover approximately 46 methods by writing only six now that's kind of
00:31:01.840
that's scalable i only had to create one t one class and through the and through that i
00:31:08.000
was able to encompass all of these possibilities neatly and cleanly by creating one
00:31:16.440
block but here's the thing as i mentioned expanding this out to the larger case again i could reuse that
00:31:22.799
same technique of using a dynamic dispatch within method missing and that's what we see here i do here's what
00:31:30.000
we just saw you send to a tense block but how do you get the tense block you'd
00:31:35.039
use the same technique you use the first three specifiers to get the block and
00:31:40.080
then you send the last two specifiers and call that on that block and that's how i was able to scale up to
00:31:46.880
meet potentially thousands of methods and provide the clustering by writing 24 methods
00:31:54.159
so for any domain where you're looking at having to type a lot until the point of carpal tunnel death i highly
00:32:01.519
recommend that you embrace the power of meta programming that ruby provides the other interesting part was
00:32:07.760
the surprises is particularly these two i coded them or i expected this result
00:32:14.159
to work this is the way we frequently refer to it in linguistics communities but then one night at the carbon 5 hack
00:32:21.279
night one of the other attendees said,"well what happens if you reverse it does it work?" and it just did so
00:32:27.440
what was a great surprise and a great bliss for me was that it turned out that the modeling algorithm the class itself
00:32:35.440
was smarter than i thought it was and as a result of this when i wrote those test cases they just passed i was expecting
00:32:41.600
to see uh test case blood all over the screen but it turned out zero errors i
00:32:46.880
thought certainly made my test method didn't run but it turned out it had run but it turned out that my class was
00:32:52.559
smart enough to handle that case the other thing i like about this is that it allows different types of
00:32:58.640
expression and it avoids what i call the java-ish parameterized brain damage
00:33:04.159
which is this which is that sometimes is imagine trying to handle all the all the
00:33:10.720
classing that would have had to go on here in the case of java and admittedly i'm not a java guru so maybe there's someone out there that wants to troll me
00:33:16.880
later but wait wait till the end for that um is that we could have done something like we could expect to get a
00:33:23.120
string back and we would pass in something like a verb type uh a bunch of
00:33:28.640
specifying strings or maybe we'd bundle them all up into an array and pass that array in or something like that but what
00:33:35.120
i really like is it allows it is that i'm now able to use the methods and the
00:33:40.240
um the terminology of the linguistics domain to get my result i just say a
00:33:46.240
verb give me your active voice indicative mood present tense first person singular number and that's exactly the tradition of how that's been
00:33:53.200
modeled modeled for the last 2,500 years working with dead languages is great because the domain is totally modeled
00:34:04.480
so um the other thing i really liked about this is it allowed me to implement the objective c style of named
00:34:11.119
parameters within methods within ruby which in my case shows that's why ruby's better than objective c is because it
00:34:17.599
can fully qualify the stylistics of the other language while still having its
00:34:23.040
own style but not really differentiating between the two i think that's really something fascinating and i think we
00:34:29.440
have to always credit the um the talent and the minds behind ruby core who gave
00:34:34.800
us a language that's flexible enough to do
00:34:40.599
that all right so that was case one case two from the latin verb
00:34:47.639
uh collection would be looking at how ancestor chains behave so this is going
00:34:53.520
to be my my uh my attempt to satisfy mr james edward grey by talking about how
00:35:00.320
we can create modules at runtime and we can still include them in a sanitary
00:35:06.640
fashion so that they're not spilling all over the namespace this makes use of uh
00:35:11.839
dsls domain specific languages i can't talk about that here with the time we have left however uh evan light did a
00:35:18.720
very good talk on it at lonear rubicon this year i'm also going to uh show the
00:35:24.320
mixin technique and i'm also going to keep my module name space clean so let's
00:35:29.760
take a real quick look uh this there are also a number of really useful quotes so i'm i've taken
00:35:37.359
these from all the mentors that i've talked to about this problem over the years um on the ruby rogues podcast
00:35:42.480
david brady says be sure to use modules uh james edward gray always says understand your your ancestor chain jim
00:35:49.440
hayrick u in the polite programmers session two ruby comps ago said always
00:35:55.280
make sure that your respond to works with metarogrammatically generated methods and lastly uh and this is still
00:36:03.200
sort of uh a bit under discussion is whether or not you should extract your
00:36:08.240
um your domain into modules so that you can do super fast testing um but this
00:36:13.760
technique serves that bullet point as well
00:36:20.520
confusing but remember i said that i wanted to be able to flexibly call potentially thousands of methods right
00:36:27.119
but i certainly didn't want to have to type them all out so that i could respond to like a polite programmer so what did i do i wrote a
00:36:34.720
dsl that created all the comb combinotaurics to produce the methods by
00:36:39.920
producing those methods i could respond to that i support them but i didn't
00:36:45.200
actually have to type them out likewise i could create those methods and i could put them into a sanitary
00:36:50.880
module and i could include that module at runtime thus keeping those metaprogrammatically generated methods
00:36:57.920
in a sandbox so that the next developer who came along could always understand the um creativity with which i
00:37:05.760
approached the problem i think a lot of us have had to debug other people's creative solutions over the years
00:37:12.480
so i created this dsl and here's how i actually use that
00:37:17.920
in the implementation of latin verb is i so this process this dsl returns this
00:37:25.839
object this generator that generator in turn i ask it create a method of all the or create
00:37:33.440
a module containing all the methods that you generated that returns that here and
00:37:38.800
then i proceed to power up anybody play altered beast good people thank oh really i'm
00:37:45.680
gonna get applause for altered beast wow all right i'll try harder um so i
00:37:51.599
proceed to take all those methods and include them into self by which point i infuse the latin verb with all of the
00:37:59.040
methods that the dsl created and here it is with a little bit
00:38:05.839
of uh debugging information in it and it's also going to be in service of uh
00:38:11.119
gray's mandate as i'm calling it as we can see before the extension the singleton class contains nine elements
00:38:19.119
after the extension we can see that it controls 10 the addition was module uh
00:38:25.280
module reference the module that i created dynamically out of that dsl has been included in the ancestor chain so
00:38:32.400
that i gain all those methods however if anyone's looking to understand where those methods came from it's no longer a
00:38:39.200
mystery we know that it had to come exclusively in this
00:38:44.440
module and by doing so i'm able to keep a sanitary namespace and here it is also showing
00:38:50.800
that the respond to works is i can provide uh i can interrogate the object
00:38:55.920
do you respond to this long method that i never had to create and it returns
00:39:01.560
true because i've uh changed the behavior of respond to based on the
00:39:06.880
inclusion of that method all that may be well and good but
00:39:14.240
here's the question what is this all in service of why create methods that you
00:39:19.920
call with a bunch of underbars instead of with a parameterized hash why do it
00:39:25.520
in one form versus another because i want to create code that not only communicates with developers but also
00:39:31.839
that communicates with the participants within that domain and i would argue that's the whole point of metarogramming
00:39:38.160
is it allows you to take the difficulty and tech the difficult and technical arg
00:39:43.680
of our trade and translate it into new domains and i think cucumber has been fairly successful at proving this point
00:39:50.079
as well so let's look back at our goals checklist i encourage you and push you
00:39:55.920
to meta program boldly remember you already are metaroming all i'm asking you to do is learn a few more methods
00:40:02.560
and feel comfortable with using them again there you are you're better
00:40:07.760
at it than you already know study and experiment remain humble listen to
00:40:12.880
mentors go to mindbending talks use the ancestor chain as your
00:40:18.800
guide it is your most assuredly your most reliable guideline for getting in in a pickle and also for getting out of
00:40:25.880
it and lastly let metaroming surprise you i think as programmers we live in this very deterministic world where we
00:40:32.560
know what to expect and when it doesn't work we're usually frustrated but here's the nice thing with metaroming
00:40:38.079
occasionally things work and you gain a new insight into the domain you're modeling and really that comes along so
00:40:43.520
rarely you should do anything you can to get that high and lastly i have to thank the ruby
00:40:49.440
rogues i kind of use them as uh my my my whipping post at the beginning but um
00:40:55.200
i know all of them are confident enough to take a little ribbing particularly from a ruby average joe like
00:41:00.839
myself um as supplementaryary information the book metarogramming rudy
00:41:05.920
is by paulo prada the list of spells is here if you want to learn how to meta
00:41:11.440
and meta program politely you can consult jim hyrick's video credit i wrote this in latte
00:41:18.960
because i'm a masochist no kidding um you can rate my
00:41:25.920
talk at speaker rate i'll show this url in the next slide um but other than that if you'd like to work with me have me
00:41:32.319
teach or would like to get in contact with me here's my contact information one more time and i think we have about
00:41:38.560
five minutes left for questions so i'll open the floor and ask that you don't troll me too
00:41:48.119
hard this is either a very good sign or a very bad sign
00:41:53.680
oh boy uh at the same time um i'm going to go for you because i saw you first that's all right how long till you can
00:41:59.040
decline now that's right um i i would have to say that my girlfriend is in the
00:42:04.400
audience and she uh would probably like me not to do that um but i've i've
00:42:11.680
actually what i'd really like to do and i talked about this a little bit earlier is i'd really like to take latin verb
00:42:16.800
and then make it subclassible um and so you could subclass latin verb into spanish
00:42:23.240
verb because then we'd have the anthropological behavior of what actually happened in reality um be
00:42:30.640
mapped in code so i like this idea that we're we're we're using code to understand our world and to understand
00:42:36.480
our the human condition um i think all art is basically our feeble attempt to do that and i think with ruby we have uh
00:42:44.000
a pallet sufficiently rich that we can come to understand our programming experience as art and i think this is
00:42:49.599
incidentally this is why people still love why uh so many years after he's he's left us is that he was an
00:42:55.200
individual who unapologetically appro approached ruby as art and as a means
00:43:00.560
for self-realization and very few programmers do that you turn in the green yeah um so i think this is an
00:43:07.839
interesting talk and it was an interesting example of meta programming that could fit in slides but i was kind
00:43:15.040
of wondering why did you end up doing all this giant method name stuff rather than doing like method chaining like
00:43:21.520
would you have chosen to do this otherwise right um a bit like how um yeah like yeah how arrol's exact example
00:43:28.880
i was thinking of the reason i chose that was because i wrapped this library inside of a hacked out session of irb
00:43:35.200
what was the question oh i'm sorry thank you he said "why did i choose long method names instead of method chaining
00:43:40.560
in in the style of eril?" uh the reason is is that i wanted to create this as a tool for linguistics learners um so for
00:43:48.480
for students and for teachers and the way they would understand how to do it is to put in the full name the within
00:43:54.800
the discipline you refer to it as active voice indicative mood blah blah blah blah um so i embedded this library
00:44:00.400
inside of irb with tab completion so that uh for people who want to get that
00:44:05.839
quick bit of information they can basically fire up latin irb also on github and proceed to use tab to
00:44:13.200
complete their way to these long method names um i also like that for just for
00:44:18.640
representing the domain purity again it's largely an aesthetic thing but um i also use the same technique to take the
00:44:24.640
same library and wrap it inside of a rails application so it allowed me a lot of portability um the long method name
00:44:31.599
is basically an interface for the complexity of the logic within so the short answer would be aesthetics the
00:44:37.839
long answer would be that um it's what consumers my my target audience would
00:44:44.200
expect but i agree i agree i i definitely have tried it the other way where basically using a series of
00:44:49.359
dynamically generated blocks returns a new object a new object a new object um
00:44:54.720
i've not benchmarked this this is largely an aesthetic endeavor but i'd definitely be open to see if there's a performance hit i'm sure there has to
00:45:01.880
be or else aaron would have done it for errol so how many latin words can you conjugate per second me personally
00:45:15.440
um not very many uh i i'm not sure how scalable this is i'm not i'm not predicting a massive outbreak of romans
00:45:22.319
anytime soon they they have very odd numbering system on their keypad so i can't
00:45:28.319
predict the numbers being that large so i mean really have you tried to type
00:45:35.119
in 55 i mean i'm trying to understand where you're where you're going with the library
00:45:41.520
because like uh amar has like a transitive and intransitive and
00:45:46.800
reflexive yes so which is not even covered on that like they give those
00:45:53.119
thousand methods times like you know we cover active voice passive voice indictive mood present mood subjunctive
00:45:58.480
mood all those possibilities are represented latin is a bit more regular than say spanish so you don't have some of these transitivity qualities but the
00:46:04.880
irregulars i've also modeled as well also the irregulars yeah i i i put that
00:46:10.000
as json so it's it's actually hardcoded sorry but latin only has five of them so spanish has a lot more french a lot more
00:46:16.480
italian way a lot more so um yeah interesting i think i saw a hand from
00:46:22.000
you sir yes please yeah how do you write test for this ah
00:46:27.040
do you really want to see the question is how do i write tests for
00:46:33.200
this and the answer is unit tests and a lot of them um
00:46:43.839
uh nope wrong one sorry that
00:46:49.400
one uh okay i guess not um the answer is that i basically wrote
00:46:56.440
um i wrote by hand unit tests so it turns out latin verbs are par are
00:47:02.400
paradigmatic they fall into five general cases so i wrote unit tests for each of the five cases and i wrote out um unit
00:47:10.000
tests for each and every one of those knowing that once i was sure that the five exemplar classes were correct that
00:47:16.079
all the other things that followed that form would behave properly so in short i used that dsl to generate all the method
00:47:22.560
names and then i used uh said and ruby to basically generate classes to do the
00:47:28.560
testing incidentally this also has a a phonetic phonetic element um it knows
00:47:33.920
when to shorten and lengthen vowels so that you get the right sound so there's a difference between a long a and a short a but this library has the
00:47:40.480
capability of understanding that as well which is why we see long bars over things occasionally um somebody else had a
00:47:47.520
question up front as well wor you all to
00:47:54.000
um well again thank you so much this has absolutely been a labor of love it's been very much quickened by the ruby community um this community really
00:48:00.880
embraces kooky ideas like no other it's definitely why i'm here and uh i'm very very glad you were all here to uh take