我正在从sinatra应用程序中将功能提取到扩展中。我的扩展模块(ExtensionBar
)取决于是否存在由另一个扩展模块(ExtensionFoo
)创建的类级别dsl扩展。因此,我的扩展程序在我的主应用程序require
d时死亡。
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 :(得分: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'