如何在Sinatra中过滤之前创建类似Rails的?

class Foo def do_before ... end def do_something ... 

有没有办法在Foo类中的每个其他方法之前运行do_before方法(比如do_something )?

看起来块之前的Sinatra before每个HTTP请求before运行,这与此类无关。

编辑:正如Michael在评论中指出的那样,Rails提供的唯一类似function是在Controller中。 但是,Rails和Sinatra都提供类似于此function的东西。

正如iain在评论中指出的那样,您指定的示例并不特定于Rails / Sinatra。 我假设你想要在filter之前像Rails中那样,这就是Sinatra提供的:

Sinatra的模块化应用程序:

 class Foo < Sinatra::Base before do "Do something" end get '/' do "Hello World" end end class Bar < Sinatra::Base before do "Do something else" end get '/' do "Hello World" end end 

config.rb文件中,

 require 'foo.rb' require 'bar.rb' map '/foo' do run Foo end map '/bar' do run Bar end 

这是Sinatra中Rails控制器最接近的类比。 创建更多这样的类,你将拥有类似的function(类似,但可能与你在Rails世界中所期望的相同)。

您还可以使用一些元编程来创建前置filter。 例如:

 class Foo def method_1; p "Method 1"; end def method_2; p "Method 2"; end def preprocess_method; p "Pre-Processing method"; end def self.before_filter m current_methods = instance_methods(false) - [m] self.new.instance_eval do current_methods.each do |meth| inst_method = public_method(meth) self.class.send :define_method,inst_method.name do public_send m inst_method.call end end end end before_filter :preprocess_method end o = Foo.new o.method_1 #output: "Pre-Processing method" "Method 1" o.method_2 #outputs "Pre-Processing method" "Method 2" 

在这种情况下,在每次调用Foo类中定义的任何实例方法之前,将调用preprocess_method (即示例中的do_before)。

不知道你在做什么使得很难知道如何回答,但是要在网上增加信息;)我将替代@fmendez的回答:

 module Filterable def self.included(base) base.extend ClassMethods end module ClassMethods def do_before( name, &block ) before_filters[name.to_sym] = block end def before_filters @before_filters ||= {} end def method_added( name ) return if name.to_s.start_with?("unfiltered_") return if before_filters.has_key? name before_filters[name.to_sym] ||= nil alias_method "unfiltered_#{name}", name define_method name do |*args,&block| self.class.before_filters[name.to_sym].call if self.class.before_filters[name.to_sym] send "unfiltered_#{name}", *args, &block end end end end class Foo include Filterable def something( x ) x * 3 end do_before :something do puts "Before…" end end Foo.new.something 4 

输出:

之前…
#= 12