4. Метапрограмиране
DESCRIPTION
TRANSCRIPT
![Page 1: 4. Метапрограмиране](https://reader033.vdocuments.mx/reader033/viewer/2022051818/5497ea60b47959d4688b4770/html5/thumbnails/1.jpg)
4. Метапрограмиране
class << selfspeaker "Стефан Кънев"speaker "Николай Бачийски"on_date "20‐10‐2008"
end
![Page 2: 4. Метапрограмиране](https://reader033.vdocuments.mx/reader033/viewer/2022051818/5497ea60b47959d4688b4770/html5/thumbnails/2.jpg)
lectures.last.recap
![Page 3: 4. Метапрограмиране](https://reader033.vdocuments.mx/reader033/viewer/2022051818/5497ea60b47959d4688b4770/html5/thumbnails/3.jpg)
class Vectordef initialize(x, y, z)@x, @y, @z = x, y, z
end
def length(@x * @x + @y * @y + @z * @z) ** 0.5
end
def to_s() “(#@x, #@y, #@z)” endend
orientation = Vector.new 1.0, 0.0, 1.0puts orientation.length
![Page 4: 4. Метапрограмиране](https://reader033.vdocuments.mx/reader033/viewer/2022051818/5497ea60b47959d4688b4770/html5/thumbnails/4.jpg)
class Vectorattr_accessor :x, :y, :z
def initialize(x, y, z)@x, @y, @z = x, y, z
endend
![Page 5: 4. Метапрограмиране](https://reader033.vdocuments.mx/reader033/viewer/2022051818/5497ea60b47959d4688b4770/html5/thumbnails/5.jpg)
class Vector
def +(other)Vector.new self.x + other.x,
self.y + other.y,self.z + other.z
end
def *(n)Vector.new @x * n, @y * n, @z * n
end
end
![Page 6: 4. Метапрограмиране](https://reader033.vdocuments.mx/reader033/viewer/2022051818/5497ea60b47959d4688b4770/html5/thumbnails/6.jpg)
class Fixnumalias broken_equal? ==
def ==(other)if (self.equal?(0) and other.equal?(1)) or
(self.equal?(1) and other.equal?(0))true
elseself.broken_equal?(other)
endend
end
![Page 7: 4. Метапрограмиране](https://reader033.vdocuments.mx/reader033/viewer/2022051818/5497ea60b47959d4688b4770/html5/thumbnails/7.jpg)
pesho = Coin.new 0.50
def pesho.pick_up(person)person.get_hopes_highperson.humiliateperson.make_sad
end
![Page 8: 4. Метапрограмиране](https://reader033.vdocuments.mx/reader033/viewer/2022051818/5497ea60b47959d4688b4770/html5/thumbnails/8.jpg)
metaprogramming.inspect
![Page 9: 4. Метапрограмиране](https://reader033.vdocuments.mx/reader033/viewer/2022051818/5497ea60b47959d4688b4770/html5/thumbnails/9.jpg)
class Student < ActiveRecord::Basevalidates_presence_of :name, :fn, :emailvalidates_numericality_of :fnvalidates_email :email
belongs_to :universityhas_many :gradeshas_many :courses, :through => :courseshas_and_belongs_to_many :groups
before_destroy do |student|InformationMailer.deliver_destroyed(student)
endend
![Page 10: 4. Метапрограмиране](https://reader033.vdocuments.mx/reader033/viewer/2022051818/5497ea60b47959d4688b4770/html5/thumbnails/10.jpg)
html :xmlns => "http://www.w3.org/1999/xhtml" dohead dotitle "Registered students"style :type => "text/css" do
content "* { font‐family: Verdana; }"end
endbody doh1 "Registered studentsul do
@students.each do |student|li dop student.nameunless student.url.nil?
a "Personal website", :href => student.urlend
endend
endend
end
![Page 11: 4. Метапрограмиране](https://reader033.vdocuments.mx/reader033/viewer/2022051818/5497ea60b47959d4688b4770/html5/thumbnails/11.jpg)
class Person; endclass Programmer < Person; endclass Rubyist < Programmer; end
>> chunky = Rubyist.new>> chunky.classRubyist>> chunky.class.superclassProgrammer>> chunky.class.ancestors[Rubyist, Programmer, Person, Object, Kernel]>> chunky.instance_of?(Rubyist), chunky.instance_of? Programmer[true, false]>> chunky.kind_of?(Rubyist), chunky.kind_of?(Programmer)[true, true]>> Rubyist < Person, Rubyist < Programmer, Person < Rubyist[true, true, false]
![Page 12: 4. Метапрограмиране](https://reader033.vdocuments.mx/reader033/viewer/2022051818/5497ea60b47959d4688b4770/html5/thumbnails/12.jpg)
respond_to?
![Page 13: 4. Метапрограмиране](https://reader033.vdocuments.mx/reader033/viewer/2022051818/5497ea60b47959d4688b4770/html5/thumbnails/13.jpg)
class Vectordef initialize(x, y, z) @x, @y, @z = x, y, z enddef length() (@x * @x + @y * @y + @z * @z) ** 0.5 enddef method_missing(name, *args)
return Vector.new(‐@x, ‐@y, ‐@z) if name.to_sym == :invertsuper
endprivatedef sum() @x + @y + @z end
end
>> vector = Vector.new 1.0, 2.0, 3.0>> vector.respond_to? :lengthtrue>> vector.respond_to? :invertfalse>> vector.respond_to? :sumfalse>> vector.respond_to?(:sum, true)false
![Page 14: 4. Метапрограмиране](https://reader033.vdocuments.mx/reader033/viewer/2022051818/5497ea60b47959d4688b4770/html5/thumbnails/14.jpg)
class Vectorattr_accessor :x, :y, :zdef initialize(x, y, z) @x, @y, @z = x, y, z end
end
>> vector = Vector.new 1.0, 2.0, 3.0>> vector.instance_variable_get :@y2.0>> vector.instance_variable_set :@y, 5.05.0>> vector.instance_variable_get :@y5.0>> vector.y5.0>> vector.instance_variables["@z", "@y", "@x"]
![Page 15: 4. Метапрограмиране](https://reader033.vdocuments.mx/reader033/viewer/2022051818/5497ea60b47959d4688b4770/html5/thumbnails/15.jpg)
public_methods(all=true)protected_methods(all=true)private_methods(all=true)
methods
![Page 16: 4. Метапрограмиране](https://reader033.vdocuments.mx/reader033/viewer/2022051818/5497ea60b47959d4688b4770/html5/thumbnails/16.jpg)
>> vector = Vector.new 1.0, 2.0, 3.0>> vector.methods["inspect", "taguri", "clone", "public_methods", "taguri=", "display", "method_missing", "instance_variable_defined?", "equal?", "freeze", "methods", "respond_to?", "dup", "instance_variables", "__id__", "method", "eql?", "id", "singleton_methods", "send", "length", "taint", "frozen?", "instance_variable_get", "__send__", "instance_of?", "to_a", "to_yaml_style", "type", "protected_methods", "instance_eval", "object_id", "require_gem", "==", "require", "===", "instance_variable_set", "kind_of?", "extend", "to_yaml_properties", "gem", "to_s", "to_yaml", "hash", "class", "private_methods", "=~", "tainted?", "untaint", "nil?", "is_a?“]>> vector.public_methods(false)["method_missing", "length"]
![Page 17: 4. Метапрограмиране](https://reader033.vdocuments.mx/reader033/viewer/2022051818/5497ea60b47959d4688b4770/html5/thumbnails/17.jpg)
method(:length)
![Page 18: 4. Метапрограмиране](https://reader033.vdocuments.mx/reader033/viewer/2022051818/5497ea60b47959d4688b4770/html5/thumbnails/18.jpg)
>> v1 = Vector.new 1.0, 0.0, 0.0>> v2 = Vector.new 0.0, 3.0, 4.0>> length = v1.method(:length)>> puts length[]1.0>> unbinded = length.unbind>> unbinded.bind(v2)[]5.0
![Page 19: 4. Метапрограмиране](https://reader033.vdocuments.mx/reader033/viewer/2022051818/5497ea60b47959d4688b4770/html5/thumbnails/19.jpg)
Vector.instance_method(:length)
![Page 20: 4. Метапрограмиране](https://reader033.vdocuments.mx/reader033/viewer/2022051818/5497ea60b47959d4688b4770/html5/thumbnails/20.jpg)
class Coin
def initialize(value)@value = value
end
def pick_up(person)person.enrich self.value
end
def put_on_train_rail!self.flatten
endend
pesho = Coin.new 0.50gosho = Coin.new 1.00
![Page 21: 4. Метапрограмиране](https://reader033.vdocuments.mx/reader033/viewer/2022051818/5497ea60b47959d4688b4770/html5/thumbnails/21.jpg)
pesho@value = 0.50
gosho@value = 1.00 Coin
pick_up(person)put_on_train_rails()
![Page 22: 4. Метапрограмиране](https://reader033.vdocuments.mx/reader033/viewer/2022051818/5497ea60b47959d4688b4770/html5/thumbnails/22.jpg)
def pesho.pick_up(person)person.get_hopes_highperson.humiliateperson.make_sad
end
def pesho.flip:heads
end
![Page 23: 4. Метапрограмиране](https://reader033.vdocuments.mx/reader033/viewer/2022051818/5497ea60b47959d4688b4770/html5/thumbnails/23.jpg)
singleton_methods
![Page 24: 4. Метапрограмиране](https://reader033.vdocuments.mx/reader033/viewer/2022051818/5497ea60b47959d4688b4770/html5/thumbnails/24.jpg)
>> pesho.singleton_methods["pick_up", "flip“]
![Page 25: 4. Метапрограмиране](https://reader033.vdocuments.mx/reader033/viewer/2022051818/5497ea60b47959d4688b4770/html5/thumbnails/25.jpg)
pesho@value = 0.50
gosho@value = 1.00 Coin
pick_up(person)put_on_train_rails()
pesho` < Coinpick_up(person)
flip()
![Page 26: 4. Метапрограмиране](https://reader033.vdocuments.mx/reader033/viewer/2022051818/5497ea60b47959d4688b4770/html5/thumbnails/26.jpg)
def pesho.pick_up(person)person.get_hopes_highperson.humiliateperson.make_sad
end
class << peshodef pick_up(person)person.get_hopes_highperson.humiliateperson.make_sad
endend
![Page 27: 4. Метапрограмиране](https://reader033.vdocuments.mx/reader033/viewer/2022051818/5497ea60b47959d4688b4770/html5/thumbnails/27.jpg)
class << peshoattr_accessor :valuealias take_from_ground pick_up
end
>> pesho.value0.50>> pesho.take_from_ground(stefan):(
![Page 28: 4. Метапрограмиране](https://reader033.vdocuments.mx/reader033/viewer/2022051818/5497ea60b47959d4688b4770/html5/thumbnails/28.jpg)
>> singleton_class = class << peshoself
end>> p pesho#<Coin:0x3ec5cf4 @value=0.50>>> p singleton_class#<Class:#<Coin:0x3ec5cf4>>>> p singleton_class != pesho.classtrue
![Page 29: 4. Метапрограмиране](https://reader033.vdocuments.mx/reader033/viewer/2022051818/5497ea60b47959d4688b4770/html5/thumbnails/29.jpg)
class Objectdef singleton_classclass << selfself
endend
end
>> pesho.singleton_class
![Page 30: 4. Метапрограмиране](https://reader033.vdocuments.mx/reader033/viewer/2022051818/5497ea60b47959d4688b4770/html5/thumbnails/30.jpg)
eval
![Page 31: 4. Метапрограмиране](https://reader033.vdocuments.mx/reader033/viewer/2022051818/5497ea60b47959d4688b4770/html5/thumbnails/31.jpg)
>> x, y = 5, 10>> code = "x + y">> sum = eval(code)>> puts sum15>> eval "def square(x) x ** 2 end">> puts square(10)100
![Page 32: 4. Метапрограмиране](https://reader033.vdocuments.mx/reader033/viewer/2022051818/5497ea60b47959d4688b4770/html5/thumbnails/32.jpg)
instance_eval
![Page 33: 4. Метапрограмиране](https://reader033.vdocuments.mx/reader033/viewer/2022051818/5497ea60b47959d4688b4770/html5/thumbnails/33.jpg)
>> v = Vector.new 1.0, 2.0, 3.0>> v.instance_eval "@x + @y + @z"6.0>> v.instance_eval { @x + @y + @z }6.0
![Page 34: 4. Метапрограмиране](https://reader033.vdocuments.mx/reader033/viewer/2022051818/5497ea60b47959d4688b4770/html5/thumbnails/34.jpg)
class_eval
![Page 35: 4. Метапрограмиране](https://reader033.vdocuments.mx/reader033/viewer/2022051818/5497ea60b47959d4688b4770/html5/thumbnails/35.jpg)
>> v = Vector.new 1.0, 2.0, 3.0>> Vector.class_eval "def sum() @x + @y + @z end">> p v.sum6.0>> Vector.class_eval do
def sum()@x + @y + @z
endend
>> p v.sum6.0
![Page 36: 4. Метапрограмиране](https://reader033.vdocuments.mx/reader033/viewer/2022051818/5497ea60b47959d4688b4770/html5/thumbnails/36.jpg)
def add_name_method(klass, given_name)klass.class_eval do
def namegiven_name
endend
end
>> add_name_method(Vector, "I, Vector")>> v = Vector.new 1.0, 2.0, 3.0>> p v.nameundefined method `given_name' for Vector
![Page 37: 4. Метапрограмиране](https://reader033.vdocuments.mx/reader033/viewer/2022051818/5497ea60b47959d4688b4770/html5/thumbnails/37.jpg)
define_method
![Page 38: 4. Метапрограмиране](https://reader033.vdocuments.mx/reader033/viewer/2022051818/5497ea60b47959d4688b4770/html5/thumbnails/38.jpg)
def add_name_method(klass, given_name)klass.send(:define_method, :name) do
given_nameend
end
>> add_name_method(Vector, "I, Vector")>> v = Vector.new 1.0, 2.0, 3.0>> p v.name"I, Vector"
![Page 39: 4. Метапрограмиране](https://reader033.vdocuments.mx/reader033/viewer/2022051818/5497ea60b47959d4688b4770/html5/thumbnails/39.jpg)
Module
![Page 40: 4. Метапрограмиране](https://reader033.vdocuments.mx/reader033/viewer/2022051818/5497ea60b47959d4688b4770/html5/thumbnails/40.jpg)
namespacemix‐in
![Page 41: 4. Метапрограмиране](https://reader033.vdocuments.mx/reader033/viewer/2022051818/5497ea60b47959d4688b4770/html5/thumbnails/41.jpg)
namespace
![Page 42: 4. Метапрограмиране](https://reader033.vdocuments.mx/reader033/viewer/2022051818/5497ea60b47959d4688b4770/html5/thumbnails/42.jpg)
module PseudoMathclass Vector
def initalize(x, y) @x, @y = x, y endend
def PseudoMath.square_root(number)number ** 0.5
end
PI = 3.0end
puts PseudoMath::PIheight = PseudoMath::Vector.new 3.0, 4.0puts PseudoMath::square_root(5)puts PseudoMath.square_root(5)
![Page 43: 4. Метапрограмиране](https://reader033.vdocuments.mx/reader033/viewer/2022051818/5497ea60b47959d4688b4770/html5/thumbnails/43.jpg)
mix‐in
![Page 44: 4. Метапрограмиране](https://reader033.vdocuments.mx/reader033/viewer/2022051818/5497ea60b47959d4688b4770/html5/thumbnails/44.jpg)
module Debugdef who_am_i?
"#{self.class.name} (\##{self.object_id})" +" #{self.to_s}"
endend
class Coininclude Debug
end
>> coin = Coin.new>> puts coin.who_am_i?Coin (#33139900) #<Coin:0x3f35978>
![Page 45: 4. Метапрограмиране](https://reader033.vdocuments.mx/reader033/viewer/2022051818/5497ea60b47959d4688b4770/html5/thumbnails/45.jpg)
>> pesho = Coin.new>> pesho.extend(Debug)>> puts Coin.who_am_i?Coin (#33139900) #<Coin:0x3f35978>
![Page 46: 4. Метапрограмиране](https://reader033.vdocuments.mx/reader033/viewer/2022051818/5497ea60b47959d4688b4770/html5/thumbnails/46.jpg)
Умни константи
![Page 47: 4. Метапрограмиране](https://reader033.vdocuments.mx/reader033/viewer/2022051818/5497ea60b47959d4688b4770/html5/thumbnails/47.jpg)
module Unicodedef self.const_missing(name)
if name.to_s =~ /^U([0‐9a‐fA‐F]{4,6})$/utf8 = [$1.to_i(16)].pack('U')const_set(name, utf8)
elseraise NameError, "Unitinitialized constant: #{name}"
endend
end
puts Unicode::U00A9puts Unicode::U221Eputs Unicode::X
![Page 48: 4. Метапрограмиране](https://reader033.vdocuments.mx/reader033/viewer/2022051818/5497ea60b47959d4688b4770/html5/thumbnails/48.jpg)
Генериране на XML
![Page 49: 4. Метапрограмиране](https://reader033.vdocuments.mx/reader033/viewer/2022051818/5497ea60b47959d4688b4770/html5/thumbnails/49.jpg)
XML.new(STDOUT) dohtml do
head dotitle { "Extrapolate me" }
endbody(:class => 'ruby')
endend
![Page 50: 4. Метапрограмиране](https://reader033.vdocuments.mx/reader033/viewer/2022051818/5497ea60b47959d4688b4770/html5/thumbnails/50.jpg)
class XMLdef initialize(out, indent=' ', &block)
@res = out@indent = indent@depth = 0self.instance_eval(&block)@res << "\n"
end
def tag(name, attributes={})
?end
alias method_missing tagend
![Page 51: 4. Метапрограмиране](https://reader033.vdocuments.mx/reader033/viewer/2022051818/5497ea60b47959d4688b4770/html5/thumbnails/51.jpg)
def tag(name, attributes={})@res << "<#{name}"attributes.each { |attr, value| @res << " #{attr}='#{value}'"}if block_given?
@res << ">"inside = yield@res << inside.to_s@res << "</#{name}>"
else@res << ' />'
endnil
end
![Page 52: 4. Метапрограмиране](https://reader033.vdocuments.mx/reader033/viewer/2022051818/5497ea60b47959d4688b4770/html5/thumbnails/52.jpg)
DSL RPG Иху‐аху
![Page 53: 4. Метапрограмиране](https://reader033.vdocuments.mx/reader033/viewer/2022051818/5497ea60b47959d4688b4770/html5/thumbnails/53.jpg)
Game.new dopencho = Singlerich.new('Pencho')kuncho = Eigendiel.new('Kuncho')
kuncho.knife penchokuncho.bow penchokuncho.sword kuncho
pencho.kick kunchoputs kuncho.health pencho.healthend
![Page 54: 4. Метапрограмиране](https://reader033.vdocuments.mx/reader033/viewer/2022051818/5497ea60b47959d4688b4770/html5/thumbnails/54.jpg)
class Eigendiel < Monster
weapons :bow, :knife
def after_bow(other)# special poison, doesn’t work on meother.hurt 2 if !other.equal?(self)
endend
![Page 55: 4. Метапрограмиране](https://reader033.vdocuments.mx/reader033/viewer/2022051818/5497ea60b47959d4688b4770/html5/thumbnails/55.jpg)
class Singlerich < Monster
weapons :knife, :sword, :kick
def before_knife(other)# kicks at the same timekick other
endend
![Page 56: 4. Метапрограмиране](https://reader033.vdocuments.mx/reader033/viewer/2022051818/5497ea60b47959d4688b4770/html5/thumbnails/56.jpg)
class Monsterattr_reader :health, :name
BASIC_DAMAGE = 11
def initialize(name)@name = name@health = 100
end
def self.weapons(*weapons_list)
?end
def hurt(amount)@health ‐= amountputs "#{@name} is a loser!\n" if @health < 0
end
end
![Page 57: 4. Метапрограмиране](https://reader033.vdocuments.mx/reader033/viewer/2022051818/5497ea60b47959d4688b4770/html5/thumbnails/57.jpg)
def self.weapons(*weapons_list)weapons_list.each do |weapon|weapon = weapon.to_sdefine_method weapon do |whom|
send "before_#{weapon}", whom if self.class.method_def...whom.hurt BASIC_DAMAGEsend "after_#{weapon}", whom if self.class.method_def...
endend
end
![Page 58: 4. Метапрограмиране](https://reader033.vdocuments.mx/reader033/viewer/2022051818/5497ea60b47959d4688b4770/html5/thumbnails/58.jpg)
Game.new dopencho = Singlerich.new('Pencho')kuncho = Eigendiel.new('Kuncho')
kuncho.knife penchokuncho.bow penchokuncho.bow kuncho
chuck = Singlerich.new("Chuck")def chuck.explode(whom)
whom.hurt 100end
chuck.explode penchochuck.explode kuncho
end