'cd' end # Execute a shell command in an external shell. define_method(:!) do process_shell_command end # Execute a command in the controller context. define_method(:':') do process_command_line end
Method Name h = {def: [], define_method: []} (' '..'~').each do |c| begin eval "def #{c}() puts '#{c}'; end" h[:def] << c rescue SyntaxError define_method(c) { puts c } h[:define_method] << c end end puts h
AbstractController class Base ... private ... def process_action(method_name, *args) send_action(method_name, *args) end alias send_action send ... ennd
hello() 'hello' end def greeting(hello = 'hola') p self.hello end end C.new.greeting #=> private method `hello' called for #<C:0x007fe7564799e8> (NoMethodError)
def hello() 'hello' end end class D def greeting C.new.hello end end D.new.greeting #=> protected method `hello' called for #<C: 0x007fc040b0de90> (NoMethodError)
def hello p 'hello' end end p um = Person.instance_method(:hello) #=> #<UnboundMethod: Person#hello> person = Person.new p meth = um.bind(person) #=> #<Method: Person#hello> meth.call #=> "hello"
hello() p 'hello' end end class Cat def hello() p 'Meow' end end um = Person.instance_method(:hello) cat = Cat.new meth = um.bind(cat) meth.call #=> bind argument must be an instance of Person (TypeError)
Greeter def hello() p 'hello' end end class Person include Greeter end class Cat define_method :hello, Person.instance_method(:hello) end Cat.new.hello #=> "hello"
work on Method#parameters The plugin code is 99% written by me Something that makes your Rails app's controller code like Merb's controller Initially named ”Merbish” I ALWAYS use this when working on Rails apps
if:) p something if if end say 'Hello', if: true #=> syntax error, unexpected keyword_end #=> syntax error, unexpected end-of-input, expecting keyword_end
Major version bump is a good chance to introduce an API incompatibility Now we have fast kwargs and binding.local_variable_get I think we're ready to revise the *args API and move to kwargs
def save_with_validation p 'Validated.' save_without_validation end alias_method_chain :save, :validation end Record.new.save #=> "Validated." #=> "Saved."
def save() p 'Saved.' end def save_with_validation p 'Validated.' save_without_validation end alias_method_chain :save, :validation end Record.new.save_without_validation #=> "Saved."
save() p 'Saving...' end def save_with_validation p 'Validating...' save_without_validation end alias_method_chain :save, :validation def save_with_callback save_without_callback p 'Calling back...' end alias_method_chain :save, :callback end Record.new.save #=> "Calling back..." #=> "Validating..." #=> "Saving..."
'Saving...' end def save_with_validation p 'Validating...' save_without_validation end alias_method_chain :save, :validation def save_with_callback save_without_callback p 'Calling back...' end alias_method_chain :save, :callback end Record.new.save_without_validation #=> "Saving..."
module ActionViewExtension module PresenceValidator def render ... super end end module LengthValidator def render ... super end end module NumericalityValidator def render ... super ennnnd module ActionView::Helpers::Tags::TextField prepend Html5Validators::ActionViewExtension::NumericalityValidator prepend Html5Validators::ActionViewExtension::LengthValidator prepend Html5Validators::ActionViewExtension::PresenceValidator end
of this method is monkey-patching Usually done from outside, rather than from inside Also Module#include should be public (Object#extend is already public)
save(*) if status = super changes_applied end status end def save(*) #:nodoc: rollback_active_record_state! do with_transaction_returning_status { super } end end def save(options={}) perform_validations(options) ? super : false end
p 'Saved.' end end module Validation def save p 'Validated.' and super end end Record.prepend Validation record = Record.new record.method(:save).super_method.call #=> "Saved."
'Saved.' end end module Validation def save() p 'Validated.' and super ennd module Callback def save() super and p 'Calling back...' ennd Record.prepend Callback, Validation method = Record.new.method(:save) method.super_method.super_method.call #=> "Saved."
Validation def save() p 'Validated.' and super ennd module Callback def save super and p 'Calling back...' ennd module Transaction def save p 'Transaction start.' and super and p 'Transaction end.' ennd Record.prepend Callback, Transaction, Validation method = Record.new.method(:save) p method.owner p method.super_method.owner #=> Callback #=> Transaction
&block) if mod == owner super_method.call(*args, &block) else super_method.call_without(mod, *args, &block) end end end ... Record.prepend Callback, Transaction, Validation method = Record.new.method(:save) method.call_without(Validation) #=> "Saved."
module M def a() end end C.prepend M p C.new.method(:a).super_method #=> #<Method: Object(C)#a> p C.new.method(:a).super_method.super_method #=> #<Method: Object(M)#a> p C.new.method(:a).super_method.super_method.super_method #=> #<Method: Object(C)#a> (and this loops...) # This should be nil
MyMonkeypatch # We want to reveal this to the end users public def foo ... end # We want to hide this from the end users private def bar ... end end Framework::Base.include MyMonkeypatch
initial implementation was more powerful and useful See my talk “Ruby 2.0 on Rails” at RubyConf 2012 https://speakerdeck.com/a_matsuda/ruby-2-dot-0-on-rails Then diminished to the current specification
the library are visible only inside the library Never exposed to the end-users (unless they explicitly call `using`) Thanks @_ksss_ for giving me an inspiration for this implementation!