Metaprogramovanie #1
Upcoming SlideShare
Loading in...5
×
 

Metaprogramovanie #1

on

  • 998 views

 

Statistics

Views

Total Views
998
Views on SlideShare
847
Embed Views
151

Actions

Likes
0
Downloads
8
Comments
0

6 Embeds 151

http://speakerrate.com 126
http://lanyrd.com 21
http://www.hanrss.com 1
http://67.207.142.125 1
http://webcache.googleusercontent.com 1
http://www.linkedin.com 1

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Metaprogramovanie #1 Metaprogramovanie #1 Presentation Transcript

  • Metaprogramovanie #1. Polopravdy o objektovom (meta) modeli mar @ tkra arla ich alb @m
  • Kód,ktorý píše kód,ktorý píše kód,ktorý píše kód..
  • class Car def engine @engine end def engine=(engine) @engine = engine endend
  • class Car attr_accessor :engine, :wheels, :brakesend
  • namespace :db do desc "Load database migrations" task :migrate do # run migrations endend
  • Presentation .find_by_event_and_name ("Rubyslava", "Metaprogramovanie")
  • Application.routes.draw do resources :events do resources :presentations get :attend, :on => :collection endend
  • class Presentation < AR::Base index do name description endend
  • 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)
  • Moduly● Namespace● Kontajner pre metódyclass Class < Module
  • module Greeter def greet puts "Hallo Welt" endendclass Application include GreeterendApplication.new.greet#=> "Hallo Welt"Application.greet#=> Undefined method "greet"
  • module Greeter def greet puts "Hallo Welt" endendclass Application extend GreeterendApplication.new.greet#=> Undefined method "greet"Application.greet#=> "Hallo Welt"
  • class Presentation < AR::Base acts_as_searchableendPresentation.new ("Metaprogramming magic")presentation.matches?(/magic/)Presentation.search(/magic/i)
  • 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
  • Open Classes class String def ends_with? pattern ... end end
  • 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
  • doc = Nokogiri::Slop(<<-eohtml) <html> <body> <p>first</p> <p>second</p> </body> </html>eohtmlassert_equal(second, doc.html.body.p[1].text)
  • module Nokogiri module Decorators module Slop def method_missing name, *args, &block list = xpath("/#{name}") list.length == 1 ? list.first : list end end endend
  • 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
  • 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
  • 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
  • Dynamic method definition
  • 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
  • H ks● included● extended● inherited● method_added● method_removed● method_undefined● singleton_method_added● ...
  • 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
  • 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
  • DatabaseTasks.list_tasksmigrate # Load database migrationsrollback # Rollback last migrations
  • class Presentation < AR::Base include SearchableendPresentation.new ("Metaprogramming magic")presentation.matches?(/magic/)Presentation.search(/magic/i)
  • 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
  • http://is.gd/metaprogramovanie