4. Метапрограмиране

Loading...

Flash Player 9 (or above) is needed to view presentations.
We have detected that you do not have it on your computer. To install it, go here.

0 comments

Post a comment

    Post a comment
    Embed Video
    Edit your comment Cancel

    Favorites, Groups & Events

    4. Метапрограмиране - Presentation Transcript

    1. 4. Метапрограмиране class << self speaker \"Стефан Кънев\" speaker \"Николай Бачийски\" on_date \"20‐10‐2008\" end
    2. lectures.last.recap
    3. class Vector def 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)” end end orientation = Vector.new 1.0, 0.0, 1.0 puts orientation.length
    4. class Vector attr_accessor :x, :y, :z def initialize(x, y, z) @x, @y, @z = x, y, z end end
    5. 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
    6. class Fixnum alias broken_equal? == def ==(other) if (self.equal?(0) and other.equal?(1)) or (self.equal?(1) and other.equal?(0)) true else self.broken_equal?(other) end end end
    7. pesho = Coin.new 0.50 def pesho.pick_up(person) person.get_hopes_high person.humiliate person.make_sad end
    8. metaprogramming.inspect
    9. class Student < ActiveRecord::Base validates_presence_of :name, :fn, :email validates_numericality_of :fn validates_email :email belongs_to :university has_many :grades has_many :courses, :through => :courses has_and_belongs_to_many :groups before_destroy do |student| InformationMailer.deliver_destroyed(student) end end
    10. html :xmlns => \"http://www.w3.org/1999/xhtml\" do head do title \"Registered students\" style :type => \"text/css\" do content \"* { font‐family: Verdana; }\" end end body do h1 \"Registered students ul do @students.each do |student| li do p student.name unless student.url.nil? a \"Personal website\", :href => student.url end end end end end end
    11. class Person; end class Programmer < Person; end class Rubyist < Programmer; end >> chunky = Rubyist.new >> chunky.class Rubyist >> chunky.class.superclass Programmer >> 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]
    12. respond_to?
    13. class Vector def initialize(x, y, z) @x, @y, @z = x, y, z end def length() (@x * @x + @y * @y + @z * @z) ** 0.5 end def method_missing(name, *args) return Vector.new(‐@x, ‐@y, ‐@z) if name.to_sym == :invert super end private def sum() @x + @y + @z end  end >> vector = Vector.new 1.0, 2.0, 3.0 >> vector.respond_to? :length true >> vector.respond_to? :invert false >> vector.respond_to? :sum false >> vector.respond_to?(:sum, true) false
    14. class Vector attr_accessor :x, :y, :z def 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 :@y 2.0 >> vector.instance_variable_set :@y, 5.0 5.0 >> vector.instance_variable_get :@y 5.0 >> vector.y 5.0 >> vector.instance_variables [\"@z\", \"@y\", \"@x\"]
    15. public_methods(all=true) protected_methods(all=true) private_methods(all=true) methods
    16. >> 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\"]
    17. method(:length)
    18. >> 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
    19. Vector.instance_method(:length)
    20. class Coin def initialize(value) @value = value end def pick_up(person) person.enrich self.value end def put_on_train_rail! self.flatten end end pesho = Coin.new 0.50 gosho = Coin.new 1.00
    21. gosho @value = 1.00 Coin pick_up(person) put_on_train_rails() pesho @value = 0.50
    22. def pesho.pick_up(person) person.get_hopes_high person.humiliate person.make_sad end def pesho.flip :heads end
    23. singleton_methods
    24. >> pesho.singleton_methods [\"pick_up\", \"flip“]
    25. gosho @value = 1.00 Coin pick_up(person) put_on_train_rails() pesho` < Coin pick_up(person) pesho flip() @value = 0.50
    26. def pesho.pick_up(person) person.get_hopes_high person.humiliate person.make_sad end class << pesho def pick_up(person) person.get_hopes_high person.humiliate person.make_sad end end
    27. class << pesho attr_accessor :value alias take_from_ground pick_up end >> pesho.value 0.50 >> pesho.take_from_ground(stefan) :(
    28. >> singleton_class = class << pesho self end >> p pesho #<Coin:0x3ec5cf4 @value=0.50> >> p singleton_class #<Class:#<Coin:0x3ec5cf4>> >> p singleton_class != pesho.class true
    29. class Object def singleton_class class << self self end end end >> pesho.singleton_class
    30. eval
    31. >> x, y = 5, 10 >> code = \"x + y\" >> sum = eval(code) >> puts sum 15 >> eval \"def square(x) x ** 2 end\" >> puts square(10) 100
    32. instance_eval
    33. >> 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
    34. class_eval
    35. >> v = Vector.new 1.0, 2.0, 3.0 >> Vector.class_eval \"def sum() @x + @y + @z end\" >> p v.sum 6.0 >> Vector.class_eval do def sum() @x + @y + @z end end >> p v.sum 6.0
    36. def add_name_method(klass, given_name) klass.class_eval do def name given_name end end end >> add_name_method(Vector, \"I, Vector\") >> v = Vector.new 1.0, 2.0, 3.0 >> p v.name undefined method `given_name' for Vector
    37. define_method
    38. def add_name_method(klass, given_name) klass.send(:define_method, :name) do given_name end end >> add_name_method(Vector, \"I, Vector\") >> v = Vector.new 1.0, 2.0, 3.0 >> p v.name \"I, Vector\"
    39. Module
    40. namespace mix‐in
    41. namespace
    42. module PseudoMath class Vector def initalize(x, y) @x, @y = x, y end end def PseudoMath.square_root(number) number ** 0.5 end PI = 3.0 end puts PseudoMath::PI height = PseudoMath::Vector.new 3.0, 4.0 puts PseudoMath::square_root(5) puts PseudoMath.square_root(5)
    43. mix‐in
    44. module Debug def who_am_i? \"#{self.class.name} (\\##{self.object_id})\" + \" #{self.to_s}\" end end class Coin include Debug end >> coin = Coin.new >> puts coin.who_am_i? Coin (#33139900) #<Coin:0x3f35978>
    45. >> pesho = Coin.new >> pesho.extend(Debug) >> puts Coin.who_am_i? Coin (#33139900) #<Coin:0x3f35978>
    46. Умни константи
    47. module Unicode def 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) else raise NameError, \"Unitinitialized constant: #{name}\" end end end puts Unicode::U00A9 puts Unicode::U221E puts Unicode::X
    48. Генериране на XML
    49. XML.new(STDOUT) do html do head do title { \"Extrapolate me\" } end body(:class => 'ruby') end end
    50. class XML def initialize(out, indent='  ', &block) @res = out @indent = indent @depth = 0 self.instance_eval(&block) @res << \"\\n\" end def tag(name, attributes={}) end ? alias method_missing tag end
    51. 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 << ' />' end nil end
    52. DSL RPG Иху‐аху
    53. Game.new do pencho = Singlerich.new('Pencho') kuncho = Eigendiel.new('Kuncho') kuncho.knife pencho kuncho.bow pencho kuncho.sword kuncho pencho.kick kuncho puts kuncho.health pencho.health end
    54. class Eigendiel < Monster weapons :bow, :knife def after_bow(other) # special poison, doesn’t work on me other.hurt 2 if !other.equal?(self) end end
    55. class Singlerich < Monster weapons :knife, :sword, :kick def before_knife(other) # kicks at the same time kick other end end
    56. class Monster attr_reader :health, :name BASIC_DAMAGE = 11 def initialize(name) @name = name @health = 100 end def self.weapons(*weapons_list) end ? def hurt(amount) @health ‐= amount puts \"#{@name} is a loser!\\n\" if @health < 0 end end
    57. def self.weapons(*weapons_list) weapons_list.each do |weapon| weapon = weapon.to_s define_method weapon do |whom| send \"before_#{weapon}\", whom if self.class.method_def... whom.hurt BASIC_DAMAGE send \"after_#{weapon}\", whom if self.class.method_def... end end end
    58. Game.new do pencho = Singlerich.new('Pencho') kuncho = Eigendiel.new('Kuncho') kuncho.knife pencho kuncho.bow pencho kuncho.bow kuncho chuck = Singlerich.new(\"Chuck\") def chuck.explode(whom) whom.hurt 100 end chuck.explode pencho chuck.explode kuncho end

    + Stefan KanevStefan Kanev, 2 years ago

    custom

    505 views, 0 favs, 0 embeds more stats

    More info about this document

    © All Rights Reserved

    Go to text version

    • Total Views 505
      • 505 on SlideShare
      • 0 from embeds
    • Comments 0
    • Favorites 0
    • Downloads 95
    Most viewed embeds

    more

    All embeds

    less

    Flagged as inappropriate Flag as inappropriate
    Flag as inappropriate

    Select your reason for flagging this presentation as inappropriate. If needed, use the feedback form to let us know more details.

    Cancel
    File a copyright complaint
    Having problems? Go to our helpdesk?

    Categories