App Academy W6D1 & D2
2 min readOct 28, 2020
exams
周一为了准备周二的考试,作为review day,其实这个形式还是蛮不错的,之前完全不理解ActiveRecord返回的东西,怎么使用,现在这几天下来,基本知道怎么用了。看来这种有考试逼迫的填鸭式教学还是最有效率的。
周二上午讲了关于meta programming的一些内容,我觉得很有用,未来可能会在建立一些自己的类的时候用到。
Learning Objectives
- Define metaprogramming
- Identify
self
in: - class definitions
- class methods
- instance methods
- Describe the difference between class variables and class instance variables
- Know how to use
send
anddefine_method
(andmethod_missing
if time allows) ********这个是重点。
Agenda
- What is metaprogramming? 用program来创建program
What is Metaprogramming?
- What is programming?
- The essence of programming is defining behavior
- Metaprogramming is defining behavior that will define future behavior
- A program is a set of instructions with some goal, ie a plan
- ex: an exercise program, television programming, the 12 step program
- Meta just means self-referential
Metaprogramming
- Often used to dynamically define a suite of similar methods based on undetermined future input to reduce duplicate code
Examples:
attr_reader
/attr_writer
belongs_to
/has_many
validates 这些function都是take in一系列的method名称,然后创建了getter和setter的,本身就是meta programming的典范。
Metaprogramming
- In practice, metaprogramming in Ruby makes use of a collection of methods to help the developer define behavior
Today we’ll explore just a small sample of those methods
require 'byebug'
class Pet
attr_reader :name
def initialize(name)
@name = name
end
def self.add_pet
@@total_pets ||= 0
@@total_pets += 1
end
def self.total_pets
@@total_pets
end
end
class Dog < Pet
puts self # Dog
def self.doggie_things
puts self # Dog
end
def who_am_i?
puts self # Dog instance
end
def self.record_dog_birth(dog)
@all_dogs ||= []
add_pet
@all_dogs << dog
end
def self.all
@all_dogs.each { |dog| puts dog.name }
end
def initialize(name)
super(name)
self.class.record_dog_birth(self)
@secret = "I'm a goat in disguise"
end
def do_this_then_that(this, that)
self.send(this) 这个就很有意思了,类似于javascript的call back function,可接收function 并执行。
self.send(that)
end
def do_this_with_args(this, *args)
self.send(this, *args)
end
def do_this_on_class(this)
Dog.send(this)
end
# def sleep
# puts "sleeping!"
# end
# def eat
# puts "eating!"
# end
# def drink
# puts "drinking!"
# end
# def self.create_tricks(*trick_names)
# puts self # Dog class
# trick_names.each do |trick_name|
# puts self # Dog class
# define_method(trick_name) do |num = 1|
# puts self # Dog instance
# num.times do
# puts "#{trick_name}ing!!!"
# end
# end
# end
# end
def method_missing(method_name, *args)
self.send(:define_method, method_name) do |*arguments|
arguments[0].times do
puts "#{method_name}ing!"
end
puts arguments[1]
end
self.send(method_name, *args)
end
def self.my_attr_reader(*method_names)
# Iterate over method names
# define methods with those names
# grab instance variables of that name
end
def trick
puts "BACK FLIP!!"
end
def juggle(thing, num)
num.times do
puts "juggling #{thing}!"
end
end
private
attr_reader :secret
def tell_secret
puts "My secret is: #{@secret}"
end
end