2012-12-05 87 views
1

我從sinatra應用程序中將功能提取到擴展中。我的擴展模塊(ExtensionBar)取決於是否存在另一個擴展模塊(ExtensionFoo)創建的類級dsl擴展。因此,當我的主應用程序require d時,我的擴展程序就會死亡。創建依賴於另一個Sinatra擴展的Sinatra擴展

my_app.rb:

require "extension_foo" 
require "extension_bar"  

class MyApp < Sinatra::Base 
    register ExtensionFoo 
    register ExtensionBar 
end 

extension_foo.rb:

module ExtensionFoo 
    def with_foo 
    yield 
    end 
end 

extension_bar.rb:

module ExtensionBar 
    with_foo do 
    "bar" 
    end 
end 

我的問題:我如何才能最有力,簡單地編寫擴展這取決於另一個擴展的註冊表?我想盡可能避免元編程。

回答

0

在你給出的例子中,ExtensionBar不會對任何應用程序做任何事情。您還需要在您希望在應用程序中使用的擴展程序中註冊附屬擴展程序。該instructions on writing modules給出了一個before塊作爲LinkBlocker DSL,這兩者都會使你的例子更象這樣的例子:

# extension_foo.rb 

require 'sinatra/base' 

module Sinatra 
    module ExtensionFoo 
    def with_foo 
     warn "Calling with_foo" 
     s = yield 
     warn "s = #{s}" 
     s 
    end 
    end 
    register ExtensionFoo 
end 


# extension_bar.rb 

require 'sinatra/base' 
require_relative 'extension_foo.rb' 

module Sinatra 
    module ExtensionBar 
    before do 
     warn "Calling with_foo in before" 
     with_foo do 
     "bar" 
     end 
    end 
    end 
    register ExtensionBar 
end 


# app.rb 

require 'sinatra' 
require_relative 'extension_bar.rb' 

get "/" do 
    with_foo do 
    "blah" 
    end.inspect 
end 

當我運行此我沒有得到一個錯誤,我看到的警告我的STDOUT,輸出是「blah」。

Calling with_foo in before 
Calling with_foo 
    from /Volumes/RubyProjects/Test/extension_dependency/extension_foo.rb:6:in `with_foo' 
s = bar 
    from /Volumes/RubyProjects/Test/extension_dependency/extension_foo.rb:8:in `with_foo' 
Calling with_foo 
    from /Volumes/RubyProjects/Test/extension_dependency/extension_foo.rb:6:in `with_foo' 
s = blah 
    from /Volumes/RubyProjects/Test/extension_dependency/extension_foo.rb:8:in `with_foo'