Met A Programming From Poignant Guide
Met A Programming From Poignant Guide
Met A Programming From Poignant Guide
You should get a cut of the salesmans commission, spoke Fox Small. Folks came out to see you kill the dragon, right?
By this time, he had aged well into his fifties and wanted to vaunt into the realm of legendary masters. So he began to construct a massive sculpture of two pears with beads of dew clinging precariously to them.
BUT!! I dont operate the tongs that actually extract the chocolava.
The sculpture was enormous and hovered
Im just sayin. You do operate the killing mechanism. So you have a stake in the ensalada. OH NO!! I left my favorite lettuce leaves in Dwemthys Array!! squealed the rabbit, twirling like a celebratory saber through the quaking oak. Distantly: Or Lesters trunk, maybe? You knowGheesh, can you stay put?? said Fox Small.
ominously above the sculptors hometown, held aloof by a massive infrastructure of struts and beams. In fact, the giant pears were so significant that they truly wreaked havoc on the Earths rotation, everso slightly, what with a new asteroid-sized fruit basket clinging to it.
My radio, said Fox Tall, stirring to life for a moment, in my pickup. The glaze still seeping from his eyes. His stare quivered and set back into his face, recalling another time and place. A drive out to Maryland. Sounds of Lionel Richie coming in so clearly. The wipers going a bit too fast. He pulls up to a house. His mother answers the door. She is a heavily fluffed fox. Tears and makeup. Slumping back down, That porcupine is changing my presets. The rabbit bounded up on to the armrest of the park bench and spoke closely. BUT!! Soon I will feast on drgns head and the juices of drgns tongue!! The rabbit sat still and held his paws kindly. (Which I hope will taste like cinnamon bears,) whispered the rabbit, intimately.
destroy the statue. They unleashed a vicious attack on the village, dismantling the statue, blowing it into thousands of pieces, chipping away at it with missiles. Soon enough, the statue was obliterated and all was back to normal.
A huge chunk of the statue had taken orbit in the heavens and often veered perilously close to the planet. When it did, it was always met by an arsenal of advanced weaponry, which further damaged it and deflected its course skyward.
I love cinammon, said Fox Small. I should go killing with you some time. You should, said the rabbit and the eyes shine-shined. Although, salivating over a tongue. You dont salivate over it, do you? I DO!! and the rabbit got so excited that Sticky Whip shot out of his eyes. (More on Sticky Whip in a later sidebar. Dont let me forget. See also: The Purists
nothing more than the size of a very daunting man. And, when it at last hit the ground, weathered and polished by its ninety year journey, it was hailed as an enigmatic masterpiece, a message from the great beyond. Here was a stunning likeness of a male nude looking wistfully into the sky with an intricate lacework of vines creeping around his waist and covering his improprieties.
The statue was last sold for fifty-two million dollars and stayed in the permanent exhibit at the Louvre, with the plaque:
Heavenly Nude by Anonymous
sidebar!
And the rabbit began expounding upon Dwemthy and the legend of Dwemthy and the ways of Dwemthy. As with most stories of Dwemthy, the rabbits tales were mostly embellishments. Smotchkkiss, there are delicacies which I alone must address.
Please, never ask who Dwemthy is. Obviously he is a mastermind and would never disclose his location or true identity. He has sired dynasties. He has set living ogres aflame. Horses everywhere smell him at all times. Most of all, he knows carnal pleasures. And to think that this This is his Array.
Dwemthys Array
You stand at the entrance of Dwemthys Array. You are a rabbit who is about to die. And deep at the end of the Array:
class Dragon < Creature life 1340 strength 451 # tough scales # bristling veins
A scalding SEETHING LAVA infiltrates the cacauphonous ENGORGED MINESHAFTS deep within the ageless canopy of the DWEMTHY FOREST... chalky and nocturnal screams from the belly of the RAVENOUS WILD
STORKUPINE... who eats wet goslings RIGHT AFTER theyve had a few graham crackers and a midday nap amidst
starved hippos TECHNICALLY ORPHANED but truthfully sheltered by umbrellas owned jointly by car dealership conglomerates beneath uncapped vials of mildly pulpy BLUE ELIXIR... which shall remain heretofore
UNDISTURBED DWEMTHY!!!
If you dont understand Dwemthys Array, it is Dwemthys fault. He designed the game to complicate our lives and were it simpler, it would not be the awe-inspiring quest weve come to cherish in our arms this very hour.
Dwemthys Array has a winding history of great depth. It is not enough to simply say, Dwemthys Array, over and over and
expect to build credentials from that act alone. Come with me, I can take you back a couple years, back to the sixties where it all started with metaprogramming and the dolphins. You might be inclined to think that metaprogramming is another hacker word and was first overheard in private phone calls between fax machines. Honest to God, I am here to tell you that it is stranger than that. Metaprogramming began with
Drugs, dolphins and deprivation. Which led to Lillys foray into things meta. He wrote books on mental
programming, comparing humans and computers. You may choose to ingest any substance you want during this next quote most likely youre reaching for the grain of salt - but I assure you that theres no Grateful Dead show on the lawn and no ravers in the basement.
When one learns to learn, one is making models, using symbols, analogizing, making metaphors, in short, inventing and using language, mathematics, art, politics, business, etc. At the critical brain (cortex) size, languages and its consequences appear. To avoid the necessity of repeating learning to learn, symbols, metaphors, models each time, I symbolize the underlying idea in these operations as metaprogramming. JOHN C. LILLY, PROGRAMMING AND METAPROGRAMMING IN THE HUMAN
All sensuous response to reality is an interpretation of it. Beetles and monkeys clearly interpret their world, and act on the basis of what they see. Our physical senses are themselves organs of interpretation. What distinguishes us from our fellow animals is that we are able in turn to interpret these interpretations. In that sense, all human language is meta-language. It is a second-order reflection on the language of our bodiesof our sensory apparatus.
seen already, which is why Dwemthy feels no qualms thrusting it at you right away. Soon enough it will be as easy to spot
as addition or subtraction. At first it may seem intensely bright, like youve stumbled across your first firefly, which has flown up in your face. Then, it becomes just a little bobbing light which makes living in Ohio so much nicer. Metaprogramming is writing code which writes code. But not as M.C. Escher would sketch it. The program isnt reaching back around and Bread Riddles
Question: Can one take five bites from a bread and make the shape of a bicycle? Answer: Yes. sidebar!
overwriting itself, nor is the program jumping onto your screen and wrenching the keyboard from your hands. No, its much smaller than
that. Lets say its more like a little orange pill you won at the circus. When you suck on it, the coating wears away and behind your teeth hatches a massive, floppy sponge brontosaurus. He slides down your tongue and leaps free, frollicking over the pastures, yelping, Papa! And from then on, whenever he freaks out and attacks a van, well, that van is sparkling clean afterwards. Now, lets say someone else puts their little orange pill under the faucet. Not on their tongue, under the faucet. And this triggers a different catalysm, which births a set of wailing sponge sextuplets. Umbilical cords and everything. Still very handy for cleaning the van. But an altogether different kind of chamois. And, one day, these eight will stir Papa to tears when they perform the violin concerto of their lives.
Question: Can a clerical error in my Question: Can one rip a bread in half and still fit the bread in an envelope? Answer: Yes.
Question: Can one man take a bread and throw it while another man sits without bread? Answer: Yes.
Metaprogramming is packing code into pill-form, such that a slender drop of water could trigger it to expand. More importantly, you can control the pills reaction, so that a brontosaurus is produced, scaly and lumbering. Or septulets, CERTAINLY. Or seamstresses. Or cat brains. Or dragons.
class Dragon < Creature life 1340 strength 451 # tough scales # bristling veins
Question: Can those same dancers, when faced with an inexplicably different scrim of bread, fail to break through? Answer: Yes.
Question: Does bread understand my darkest fears and wildest dreams? Answer: Yes.
This is not metaprogramming yet. Only the pill. The product of metaprogramming. We are pausing, looking at the beast itself before descending beneath its flesh with a scalpel and microscope. The
Dragon is a class. Youve seen that many times now. The Dragon is a Creature class. Creature class contains the metaprogramming
descendant of the
Question: Can one robot take eight bites on a bread, without knowing its there, and make
code. You can write metaprogramming code which can be used everywhere, throughout Ruby, in
anywhere. Our example here, since this is the most common form of meta-code, focuses on metaprogramming inside your own classes only. Each of the as:
Dragon s traits are simply class methods. You could also write this
class Dragon < Creature life( 1340 ) strength( 451 ) # tough scales # bristling veins
Removing the parens removes clutter, so lets leave them out. Only use parens when you are using several methods together and you want to be very clear.
Yes.
Creature Code
Now, with a lateral slice across the diaphragm, we expose the innards of
# Get a metaclass for this class def self.metaclass; class << self; self; end; end
# Advanced metaprogramming code for nice, clean traits def self.traits( *arr ) return @traits if arr.empty?
# 2. Add a new class method to for each trait. arr.each do |a| metaclass.instance_eval do define_method( a ) do |val| @traits ||= {} @traits[a] = val end end end
# 3. For each monster, the `initialize' method # should use the default number for each trait.
end
# Creature attributes are read-only traits :life, :strength, :charisma, :weapon end
Focus on the closing lines of code, specifically the line where the sets up the
traits are being set up. All of the code before that line
traits class method. This bears resemblance to the basic lottery tickets from the chapter previous.
Both
traits and attr_reader are simply class methods. When attr_reader is used in the
LotteryTicket , metaprogramming kicks in behind the scenes and starts blowing up balloons, creating reader
methods for the instance variables
traits method is the metaprogramming Ive been alluding to. Comments in the code reveal the three
life class method is added for a :life trait.) These class methods are traits or attr_accessor . This way, you can specify the trait,
along with the points given for a trait to a certain creature. 3. Add an initialize method which sets up a new monster properly, grabbing the right points and POWER UP! POWER
The beauty of these three steps is that youve taught Ruby how to code monsters for you. So when Ruby gets to the
traits :
class Creature traits :life, :strength, :charisma, :weapon end
Ruby fills in the code behind the scenes and transplants a spiny green heart and jumpstarts the body with a pullcord. Ruby will use the metaprogramming from the list like this:
Creature class and build out all the various methods, expanding the traits
class Creature
# 1. set up reader and writer methods attr_accessor :life, :strength, :charisma, :weapon
# 2. add new class methods to use in creature def self.life( val ) @traits ||= {} @traits['life'] = val end
end
Dragon code, short enough to look nice when printed on playing cards:
class Dragon < Creature life 1340 strength 451 # tough scales # bristling veins
instance_eval and class_eval . Just rub some tiger balm on your joints while
eval .
Weve been talking about metaprogramming. Writing code which writes code. The alley. The vagrant
eval takes code you have stored up in a string and it executes that code.
drgn = Dragon.new # is identical to... drgn = eval( "Dragon.new" ) # or, alternatively... eval( "drgn = Dragon.new" )
Here, lets write a program which has a hole in it. Instead of writing a program which creates a new hole where the
print "What monster class have you come to battle? " monster_class = gets eval( "monster = " + monster_class + ".new" ) p monster
"Dragon" . Inside the eval , a few strings get added together to make the string "monster = Dragon.new" . And when the eval executes this string, the monster variable contains a Dragon object.
Ready for battle. This is great! Now we can leave it up to the player to pick a monster! Of course, were trusting the player to supply a real monster class. If they type in
eval lets you make up code as you go. Which can be useful and which can be dangerous as well.
The
instance_eval and class_eval method used in the metaprogramming for the Creature class are eval . These two special methods run code just like eval does, but they duck into
irb> end
# The class_eval method runs code is if inside a class definition. irb> Dragon.class_eval do irb> def name; @name; end
irb> end
instance_eval and class_eval methods also can take a code block instead of a
dwemthy.rb .
class Creature
# This method applies a hit taken during a fight. def hit( damage ) p_up = rand( charisma ) if p_up % 9 == 7 @life += p_up / 4 puts "[#{ self.class } magick powers up #{ p_up }!]" end @life -= damage puts "[#{ self.class } has died.]" if @life <= 0 end
# This method takes one turn in a fight. def fight( enemy, weapon ) if life <= 0 puts "[#{ self.class } is too dead to fight!]" return end
# Attack the opponent your_hit = rand( strength + weapon ) puts "[You hit with #{ your_hit } points of damage!]" enemy.hit( your_hit )
# Retaliation p enemy if enemy.life > 0 enemy_hit = rand( enemy.strength + enemy.weapon ) puts "[Your enemy hit with #{ enemy_hit } points of damage!]" self.hit( enemy_hit ) end end
end
class DwemthysArray < Array alias _inspect inspect def inspect; "#<#{ self.class }#{ _inspect }>"; end def method_missing( meth, *args ) answer = first.send( meth, *args ) if first.life <= 0
shift if empty? puts "[Whoa. else puts "[Get ready. #{ first.class } has emerged.]" end end answer || 0 end end You decimated Dwemthy's Array!]"
Creature . The hit method which reacts to a hit from another Creature . And
fight method which lets you place your own blows against that Creature . Creature takes a hit, a bit of defense kicks in and your charisma value is used to generate a power-up. @life += p_up / 4 .
When your
Dont ask me to explain the secrets behind this phenomenon. A random number is picked, some simple math is done, and, if youre lucky, you get a couple life points.
The
fight method checks to see if your Creature is alive. Next, a random hit is placed on your opponent. If your Creature#fight
opponent lives through the hit, it gets a chance to strike back. Those are the workings of the method. Ill explain now.
DwemthysArray in a second. I really will. Im having fun doing it. Lets stick with hitting and fighting for
Introducing: You.
You may certainly tinker with derivations on this rabbit. But official Dwemthy Paradigms explicitly denote the code - and the altogether character - inscribed below. Save this as
rabbit.rb .
# little boomerang def ^( enemy ) fight( enemy, 13 ) end # the hero's sword is unlimited!! def /( enemy ) fight( enemy, rand( 4 + ( ( enemy.life % 10 ) ** 2 ) ) ) end
# lettuce will build your strength and extra ruffage # will fly in the face of your opponent!! def %( enemy ) lettuce = rand( charisma ) puts "[Healthy lettuce gives you #{ lettuce } life points!!]" @life += lettuce fight( enemy, 0 ) end # bombs, but you only have three!! def *( enemy ) if @bombs.zero? puts "[UHN!! You're out of bombs!!]" return end @bombs -= 1 fight( enemy, 86 ) end end
You have four weapons. The boomerang. The heros sword. The lettuce. And the bombs. To start off, open up
Good, good.
ScubaArgentine .
class ScubaArgentine < Creature life 46 strength 35 charisma 91 weapon 2 end
To get the fight started, make sure youve created one of you and one of the
ScubaArgentine .
For crying out loud!! Our sample rabbit died!! Grim prospects. I cant ask you to return to the rabbit kingdom, though. Just pretend like you didnt die and make a whole new rabbit.
irb> r = Rabbit.new
sidebar!
Which is why Ive authored a competing story which I believe uncovers an entirely different and very relevant intellectual scenario.
There was a guy who had been around the block. And he wasnt very old, so he decided to write a biography of his life.
Pretty neat looking, wouldnt you say? The code in symbols which work only with the
behavior of math operators. After all, math operators are just methods!
Well, he started to lie in his biography. He
made up some stories. But mostly little stories that were inconsequential. Filler. Like he had a story about a painting hed done of a red background with elephant legs in front.
Where it makes sense, you may choose to use math operators on some of your Classes. Ruby uses these math operators on many of its own classes. Arrays, for example, have a handful of math operators which you can see in the list of instance methods when you type:
sold at.
Anyway, he really started to like that story (and others like it), to the point where he started to ignore his friends and family, instead preferring to watch what his lie self did after the auction. In his head.
ri Array .
# the plus operator combines two arrays into a single array irb> ["D", "W", "E"] + ["M", "T", "H", "Y"] => ["D", "W", "E", "M", "T", "H", "Y"]
So, then, one day he was shopping and he found a pair of shoes that had stripey laces. And he grabbed the shoes and went to the store counter, forcing them in the cashiers face, yelling, Look! Look at these! Look! These are the shoes my lie self would wear! And he bought the shoes and put them on and the whole Earth cracked open and the cash register popped open and swallowed him up and he was suddenly elsewhere, in his lie apartment, sitting down to paint dolphin noses, three of them on a green background.
# minus removes all items in the second array found in the first irb> ["D", "W", "E", "M", "T", "H", "Y"] - ["W", "T"] => ["D", "E", "M", "H", "Y"]
# the multiplier repeats the elements of an array irb> ["D", "W"] * 3 => ["D", "W", "D", "W", "D", "W"]
You may be wondering: what does this mean for math, though? What if I add the number three to an array? What if I add a string and a number? How is Ruby
going to react?
It was a lot of work, painting all those noses.
Please remember these operators are just methods. But, since these operators arent
And he went broke for a while and had to stoop so low as to filming abominable snowman NASCAR. sidebar!
the operators are identical to other readable methods. You can then choose to use the
class AssistantViceTentacleAndOmbudsman < Creature life 320 strength 6 charisma 144 weapon 50 end
class TeethDeer < Creature life 655 strength 192 charisma 19 weapon 109 end
class IntrepidDecomposedCyclist < Creature life 901 strength 560 charisma 422 weapon 105 end
class Dragon < Creature life 1340 strength 451 # tough scales # bristling veins
These are the living, breathing monstrosities of Dwemthys Array. I dont know how they got there. No one knows. Actually, Im guessing the
If its really important for you to know, lets just say the others were born there. Can we move on?? As Dwemthys Array gets deeper, the challenge becomes more difficult.
dwary = DwemthysArray[IndustrialRaverMonkey.new, DwarvenAngel.new, AssistantViceTentacleAndOmbudsman.new, TeethDeer.new, IntrepidDecomposedCyclist.new, Dragon.new]
Fight the Array and the monsters will appear as you go. Godspeed and may you return with harrowing tales and nary an angel talon piercing through your shoulder. Start here:
irb> r % dwary
Oh, and none of this Im too young to die business. Im sick of that crap. Im not going to have you insulting our undead young people. They are our future. After our future is over, that is.
and, thus, behaves just like one. For being such a mystery, its alarmingly brief, yeah? So its an Array. Filled with monsters. But what does this extra code do?
Inspect
The
inspect method isnt really a necessary part of Dwemthys Array. Its something Dwemthy added as a courtesy to his
guests. (Many call him twisted, many call him austere, but wed all be ignorant to go without admiring the footwork he puts in for us.) Every object in Ruby has an
inspect method. It is defined in the Object class, so it trickles down through the
Have you noticed this? Whenever we create an object in name badge for the object. The
inspect method creates that name badge. The badge is just a string.
irb> class Rabbit irb> irb> irb> attr_accessor :slogan def initialize s; @slogan = s; end def inspect; "#<#{ self.class } says '#{ @slogan }'>"; end
irb> end
irb> Rabbit.new "i blow'd the drgn's face off!!" => #<Rabbit says 'i blow'd the drgn's face off!!'> irb> FakeRabbit.new "Thusly and thusly and thusly..." => #<FakeRabbit says 'Thusly and thusly and thusly...'>
irb is talking back. Every time you run some code in irb , the return value from that code is inspected. irb . And irb is just reiterating what youre saying so you can see it
How handy. Its a little conversation between you and for your self. You could write your own Ruby prompt very easily:
loop do print ">> " puts end "=> " + eval( gets ).inspect
This prompt wont let you write Ruby code longer than a single line. Its the essence of interactive Ruby, though. How do you like that? Two of your recently learned concepts have come together in a most flavorful way. The and runs it. The response from
eval is then inspected. irb , Dwemthys Array will be inspected and replying with the monsters you have left
Method Missing
Dont you hate it when you yell Deirdre! and like ten people answer? That never happens in Ruby. If you call the
deirdre method, only one deirdre method answers. You cant have two methods named the same. If you add a
second
puts "But no one is there yet." end def deirdre( *args ) puts "Deirdre is right here and you say:" args.each { |say| puts " " + say }
puts "And she loves every second of it." puts "(I think she thinks you're poetic.)" end
When you call the method and your dazzling poetry. But what if you call
deirdre above, Im sure you know what will happen. Deirdre will love every second of it, you
simon ?
irb> NameCaller.new.simon( 'Hello?', 'Hello? Simon?' ) You're calling `simon' and you say: Hello? Hello? Simon? But no one is there yet.
Yes,
method_missing is like an answering machine, which intercepts your method call. In Dwemthys Array we use
call forwarding, so that when you attack the Array, it passes that attack on straight to the first monster in the Array.
def method_missing( meth, *args ) answer = first.send( meth, *args ) # ... snipped code here ...
end
Anyway, you must admit hes a terrible President, said Fox Small. Why does President Marcos have a rabbit as Vice President of the Foxes. The Vice President? The rabbit with the eyebrows? No, the rabbit with the huge sausage lips, said Fox Small. But their conversation was abruptly interupted by a freckly cat head which popped from the sky just above the sidewalk.