Metaprogramovanie #1

1,005 views

Published on

Published in: Technology, Design
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
1,005
On SlideShare
0
From Embeds
0
Number of Embeds
163
Actions
Shares
0
Downloads
11
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Metaprogramovanie #1

  1. 1. Metaprogramovanie #1. Polopravdy o objektovom (meta) modeli mar @ tkra arla ich alb @m
  2. 2. Kód,ktorý píše kód,ktorý píše kód,ktorý píše kód..
  3. 3. class Car def engine @engine end def engine=(engine) @engine = engine endend
  4. 4. class Car attr_accessor :engine, :wheels, :brakesend
  5. 5. namespace :db do desc "Load database migrations" task :migrate do # run migrations endend
  6. 6. Presentation .find_by_event_and_name ("Rubyslava", "Metaprogramovanie")
  7. 7. Application.routes.draw do resources :events do resources :presentations get :attend, :on => :collection endend
  8. 8. class Presentation < AR::Base index do name description endend
  9. 9. Základné kamenemetaprogramovania ● premakaný objektový model ○ dynamic method lookup ○ moduly (include, extend) ● open classes ● self a kontexty ● všetko je vykonateľný kód ● callbacky ● pohadzovateľný kód (bloky)
  10. 10. Moduly● Namespace● Kontajner pre metódyclass Class < Module
  11. 11. module Greeter def greet puts "Hallo Welt" endendclass Application include GreeterendApplication.new.greet#=> "Hallo Welt"Application.greet#=> Undefined method "greet"
  12. 12. module Greeter def greet puts "Hallo Welt" endendclass Application extend GreeterendApplication.new.greet#=> Undefined method "greet"Application.greet#=> "Hallo Welt"
  13. 13. class Presentation < AR::Base acts_as_searchableendPresentation.new ("Metaprogramming magic")presentation.matches?(/magic/)Presentation.search(/magic/i)
  14. 14. module Searchable def acts_as_searchable include InstanceMethods extend ClassMethods end module ClassMethods def search(pattern) all.select { |m| m.description =~ pattern } end end module InstanceMethods def matches?(pattern) description =~ pattern end endendActiveRecord::Base.extend Searchable
  15. 15. Open Classes class String def ends_with? pattern ... end end
  16. 16. Dynamic methodlookup Object + equals?abacus1 = Abacus.new("2 + 3") Calculatorabacus2 = Abacus.new("3 - 2")abacus1.add_stone + eval_expressionabacus1.equals? abacus2abacus1.reset Abacus + add_stone
  17. 17. doc = Nokogiri::Slop(<<-eohtml) <html> <body> <p>first</p> <p>second</p> </body> </html>eohtmlassert_equal(second, doc.html.body.p[1].text)
  18. 18. module Nokogiri module Decorators module Slop def method_missing name, *args, &block list = xpath("/#{name}") list.length == 1 ? list.first : list end end endend
  19. 19. Product.find_by_name_and_description(Rubyslava, Meta)class ActiveRecord::Base def method_missing(name, *args, &block) if name.to_s =~ /^find_by_(.+)$/ run_find_by_method($1, *args, &block) else super end end def run_find_by_method(attrs, *args, &block) # args => [Rubyslava, Meta] attrs = attrs.split(_and_) #=> [name, description] attrs_with_args = [attrs, args].transpose #=> [[name, Rubyslava], [description, Meta] conditions = Hash[attrs_with_args] #=> {name => Rubyslava, description => Meta} where(conditions).all endend
  20. 20. class Color RGB = { red: #ff0000, blue: #0000ff, orange: #bb12ee } def initialize(rgb) @rgb = rgb end def to_s @rgb end def self.const_missing(name) rgb = RGB[name.downcase] if rgb Color.new(rgb) else super end endendputs Color::Blue
  21. 21. Dynamic method calldef dispatcher(klass, method) klass.send methodendmethod_names = public_instance_methods(true)tests = method_names.delete_if do |method_name| method_name !~ /^test./endtests.each do |test| send testend
  22. 22. Dynamic method definition
  23. 23. module SimpleRouting def resources(*names) names.each do |resource| define_method "#{resource}_path" do "localhost/#{resource}" end end endendclass Application extend SimpleRouting resources :events, :presenters, :topics def test_paths puts events_path #=> localhost/events puts presenters_path #=> localhost/presenters puts topics_path #=> localhost/topics endend
  24. 24. H ks● included● extended● inherited● method_added● method_removed● method_undefined● singleton_method_added● ...
  25. 25. class DatabaseTasks extend SimpleRake desc "Load database migrations" def migrate puts "Migrating.." end desc "Rollback last migrations" def rollback puts "Rolling back" endendDatabaseTasks.list_tasks
  26. 26. module SimpleRake @@methods = {} def desc(description) @@description = description end def method_added(name) @@methods[name] = @@description end def list_tasks @@methods.each do |method, desc| puts "#{method} # #{desc}" end endend
  27. 27. DatabaseTasks.list_tasksmigrate # Load database migrationsrollback # Rollback last migrations
  28. 28. class Presentation < AR::Base include SearchableendPresentation.new ("Metaprogramming magic")presentation.matches?(/magic/)Presentation.search(/magic/i)
  29. 29. module Searchable def self.included(base) base.extend ClassMethods end def matches?(pattern) description =~ pattern end module ClassMethods def search(pattern) all.select do |m| m.description =~ pattern end end endend
  30. 30. http://is.gd/metaprogramovanie

×