aspectory
文件大小: unknow
源码售价: 5 个金币 积分规则     积分充值
资源说明:Callbacks for your classes
h1. Aspectory

h2. Callbacks for Ruby.

h3. How it works

Basically, you get three methods: @before@, @after@ and @around@. Each of
these takes a method name, then a splat args of symbols and/or a block. The
symbols/block will be called before/after the method you specified.

The @around@ callback gets passed a proc, in the form of an unnamed block
for handlers that are methods and a block argument for handlers that are
blocks. You must @yield@ or @call@ that block in order for the original
method to be called.

h3. Simple Example

require 'rubygems'
require 'aspectory'
require 'spec'

class Something
  include Aspectory::Hook

  attr_reader :results

  around :foo, :round
  before :foo, :setup
  after  :foo, :teardown

  before :bar do
    @results << :before
  end

  around :bar do |fn|
    @results << :start
    fn.call
    @results << :finish
  end

  after :bar do
    @results << :after
  end

  def initialize
    @results = []
  end

  def foo; @results << :foo; :foo end
  def bar; @results << :bar; :bar end

  def round
    @results << :start
    yield
    @results << :finish
  end

  def setup
    @results << :setup
  end

  def teardown
    @results << :teardown
  end
end

something = Something.new
p something.foo # => :foo
p something.results # => [:setup, :start, :foo, :finish, :teardown]

something = Something.new
p something.bar # => :bar
p something.results # => [:before, :start, :bar, :finish, :after]
something = Something.new
something.foo # => :foo
something.results # => [:setup, :foo, :teardown]

something = Something.new
something.bar # => :bar
something.results # => [:before, :bar, :after]
h3. Calling Methods without Callbacks You can use the @#__PRISTINE__@ method to call your methods without any callbacks, or you can just call @method_name_without_callbacks@. Here's an example with the same example class we used above:
something = Something.new
something.__PRISTINE__(:foo)
something.results # => [:foo]
something.bar_without_callbacks
something.results # => [:foo, :bar]
h3. Preventing a method from being called If a @before@ callback returns @false@, then the original method will not be called. If you want to halt the method being called, but still want to provide a return value, you can @throw@ the name of the method:
class Something
  before :foo do
    throw :foo, "from the callback"
  end

  def foo
    "from the method"
  end
end

Something.new.foo # => "from the callback"
h3. @after@ callbacks get the results of the method call Your @after@ callbacks will be passed whatever the original method call returned:
class Something
  attr_reader :name

  after :foo do |result|
    @name = result.to_s.capitalize
  end
  
  def foo
    :foo
  end
end
something = Something.new
something.name # => nil
something.foo  # => :foo
something.name # => "Foo"
h3. Observing method definitions If you ever want to see when a method is defined in a class, you can register observers using the @observe@ method. It can take either a symbol or a regular expression, then a callback block will be called when the method is defined. The callback block will be passed the name of the method defined. To observe class method definitions, you must pass the @:meta@ option.
class Framework
  include Aspectory
  
  # Using a symbol
  observe :admin? do
    puts "Warning! Overriding the admin method can be dangerous."
  end

  # Using a regular expression
  observe(/^_/) do |method_id|
    puts "Warning! The #{method_id} is not part of the public API!"
  end
  
  # Observing a class method definition
  observe(:find_by_name, :meta => true) do
    puts "The method :find_by_name already exists in the framework."
  end
  
  # Observing multiple occurrences of a method definition
  observe(/^show_by_/, :times => true) do |method_id|
    puts "dynamic showing defined: #{method_id}"
  end
end
h3. Why? Why not? h3. Requirements * "nakajima":http://github.com/nakajima/nakajima @gem install nakajima-nakajima --source=http://gems.github.com@ h4. TODO * Filters (@:if@ and/or @:unless@) * Compilable callbacks ("http://gist.github.com/50397":http://gist.github.com/50397) * Maybe don't worry about @instance_eval@'ing or @instance_exec@'ing callback blocks. * Figure out a way to get it working with metaclasses * Spec suite could definitely be more readable h4. Alternatives: * http://github.com/sam/extlib/tree/master/lib/extlib/hook.rb * "AspectR":http://aspectr.sourceforge.net * "Aquarium":http://aquarium.rubyforge.org/ h4. "View the CI build":http://ci.patnakajima.com/booty-call @(c) Copyright 2008 Pat Nakajima, released under MIT License.@

本源码包内暂不包含可直接显示的源代码文件,请下载源码包。