Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Metaprogramowanie dla początkujących

Metaprogramowanie dla początkujących

Po dwóch miesiącach pracy w Three of Coins jako młodsza programistka postanowiłam podzielić się z uczestnikami/czkami WRUGa moją przygodą w cudownym świecie metaprogramowania.

Marta Paciorkowska

September 12, 2013
Tweet

More Decks by Marta Paciorkowska

Other Decks in Programming

Transcript

  1. Mówię do ciebie, jeśli: • Dopiero zaczynasz • Zacząłeś/zaczęłaś tak

    dawno, że nie pamiętasz, jak to było • Masz techniczne wykształcenie... albo nie.
  2. class TinyConfig < BasicObject # większość klasy pominięta def load(glob)

    glob = ::File.join(::File.dirname(::Kernel.caller.first), glob) load_helper(glob) end def bulk_load caller_path = ::Kernel.caller.first.sub(/(:\d+)?(:in .*)?$/, '') directory_name = ::File.join( ::File.dirname(caller_path), ::File.basename(caller_path, ".rb")) bulk_glob = ::File.join(directory_name, "*.rb") load_helper(bulk_glob) end end
  3. module Vendorificator class Config #większość klasy pominięta def read_file(filename) pathname

    = Pathname.new(filename).cleanpath.expand_path @configuration[:vendorfile_path] = pathname @configuration[:root_dir] = if pathname.basename.to_s == 'vendor.rb' && pathname.dirname.basename.to_s == 'config' pathname.dirname.dirname else pathname.dirname end instance_eval(IO.read(filename), filename, 1) end end end
  4. module Vendorificator class Config < TinyConfig #większość klasy pominięta def

    read_file(filename) pathname = Pathname.new(filename).cleanpath.expand_path @configuration[:vendorfile_path] = pathname @configuration[:root_dir] = if pathname.basename.to_s == 'vendor.rb' && pathname.dirname.basename.to_s == 'config' pathname.dirname.dirname else pathname.dirname end instance_eval(IO.read(filename), filename, 1) end end end
  5. $ rake spec mkdir -p tmp Run options: --seed 12619

    # Running: .EEEEEEEEEEEEEEEEEEEEEEEEEE..EEEEEEEEEEEEEEEEEEE 1) Error: Vendorificator::Config#test_0001_allows to set and get values: SystemStackError: stack level too deep /path/to/repo/lib/config.rb:77 48 runs, 16 assertions, 0 failures, 45 errors, 0 skips rake aborted!
  6. module Vendorificator class Config #większość klasy pominięta def method_missing(method_symbol, *args,

    &block) if modules.keys.include? method_symbol modules[method_symbol].new(environment, args.delete_at(0).to_s, *args, &block) else super end end end end
  7. def method_missing(meth, *args, &block) #this is were the magic happens

    end + Unikamy niespodzianek (...w teorii) + definiujemy metody na bieżąco... - ...ale po kryjomu
  8. Refactoring <3 metaprogramowanie yield twoim przyjacielem... prawda? def a_method(a, b)

    a + yield(a, b) end a_method(1, 2) {|x, y| (x + y) * 3 } # => 10 define_method hurtowo tworzy metody, oszczędzając miejsce
  9. pry Wpisz w konsoli: $ gem install pry Lub dodaj

    gem 'pry' do Gemfile $ bundle install Chcesz się gdzieś zatrzymać? Dodaj do kodu: require 'pry' ; binding.pry
  10. Problemy dla osoby początkującej Alicja w krainie debuggingu, po złej

    stronie lustra Rubiowa czarna magia może przytłaczać Czy metaprogramowanie to lenistwo? Komu mogę ufać?
  11. Szanse dla osoby początkującej Ćwiczę umysł Ambitne => motywujące Lepsze

    zrozumienie mechanizmów działania języka Przyspieszony kurs myślenia w Ruby... Pisanie aplikacji webowych nigdy nie było prostsze!
  12. Warto: • Eloquent Ruby, Russ Olsen: http://eloquentruby.com/ • Metaprogramming Ruby:

    Program Like the Ruby Pros, Paolo Perrotta • Confident Ruby, Avdi Grimm: http://confidentruby.com/ • Thoughtbot: http://robots.thoughtbot.com/ • Ruby Rogues: http://rubyrogues.com/