Created
April 4, 2017 16:44
-
-
Save dbrady/08a5be3ebccd76c95113744cfab468e7 to your computer and use it in GitHub Desktop.
Yo Dawg, Herd U Like DSLs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Person | |
def poop | |
puts "I pooped today!" | |
end | |
# One common way to make a class method is to declare it amongst the instance | |
# methods prefixed with self... | |
def self.poop! | |
puts "Everybody pooped today!" | |
end | |
class << self | |
# The other common way is to open Class:Person "with class << self" declare | |
# it as an instance method in there. | |
def poo! | |
puts "Everybody went poo today!" | |
end | |
# But what happens if you declare a self. method inside << self? | |
def self.poopy | |
puts "Something just went poopy. I have no idea what, or where, but I suspect it was messy." | |
end | |
end | |
end | |
Person.new.poop | |
# => I pooped today! | |
Person.poop! | |
# => Everybody pooped today! | |
Person.poo! | |
# => Everybody went poo today! | |
# But where is "poopy"? | |
# No idea how to call the "poopy" method directly. If I evaluate self from | |
# inside the << self scope, it is #<Class:Person> but the method does not appear | |
# on the class interface of Person or Class. Is #<Class:Person> the | |
# meta/eigen/wotsitclass? | |
# Hmm... let's try to see where we are at each point: | |
# 2.2.2 :063 > class Person | |
# 2.2.2 :064?> puts "Hello from #{self}" | |
# 2.2.2 :065?> class << self | |
# 2.2.2 :066?> puts "Hello from #{self}" | |
# 2.2.2 :067?> class << self | |
# 2.2.2 :068?> puts "Hello from #{self}" | |
# 2.2.2 :069?> end | |
# 2.2.2 :070?> end | |
# 2.2.2 :071?> end | |
# Hello from Person | |
# Hello from #<Class:Person> | |
# Hello from #<Class:#<Class:Person>> | |
# AH-HA! Okay, I still don't know exactly what's going on, BUT I do know that | |
# instance methods declared on self inside a class become class methods on that | |
# class: | |
# 2.2.2 :077 > class Person | |
# 2.2.2 :078?> poop! | |
# 2.2.2 :079?> end | |
# Everybody pooped today! | |
# Okay. So again, I still don't know the WHY, but I now at least know HOW to | |
# call that method: as a DSL/class method from INSIDE the superclass: | |
# 2.2.2 :080 > class Person | |
# 2.2.2 :081?> class << self | |
# 2.2.2 :082?> poopy | |
# 2.2.2 :083?> end | |
# 2.2.2 :084?> end | |
# Something just went poopy. I have no idea what, or where, but I suspect it was | |
# messy. | |
# AND BOOM. | |
# I don't know why I would ever need this skill, and I pray that I never use it | |
# in anger. I'm putting this in my satchel full of rusty shivs: Sometimes I get | |
# cornered in a dark alley at night, and when that happens I'd rather have a | |
# rusty shiv than empty hands. | |
# TL;DR This should be called "Yo Dawg, Herd U Like DSLs, So we put a DSL in yo | |
# DSL so you can DSL while you DSL." |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment