在实例变量出现时,实例变量将自己附加到任何对象本身。
从表面上看,这些是自我的价值观:
class App < Sinatra::Base
#In here, self=App
#When a block executes, it sees the value for self that existed in
#the surrounding scope at the time the block was CREATED:
configure do #a block
#So...in here self=App
@logger = Logger.new "./log"
end
@logger.info "App started" #this line works
get "/info" do #a block
#Similarly, in here self=App
@logger.info "/info inquired" #@logger is NilClass
end
end
基于这种情况,你是正确的:看起来当 configure() 执行传递给它的块时,@logger 会出现并附加到 App,然后当 get()调用传递给它的块,@logger 实例变量将引用附加到 App 的实例变量。
但是...ruby 提供了一些方法来更改当块执行时块看到的 self 的值。这是一个例子:
p = Proc.new { puts self }
p.call
class Dog
def initialize(a_proc)
#In here, self is a Dog instance
instance_eval &a_proc
end
end
Dog.new p
--output:--
main
#<Dog:0x000001009b6080>
根据您的错误,您必须怀疑 Sinatra 在执行传递给 get() 的块时必须使用一些 ruby 技巧来更改 self。
我们怎么知道这个?
Ruby 是编程语言的狂野西部,因此除非您查看源代码或好的文档(如果存在),否则您永远无法知道会发生什么。源代码相当复杂。我在文档中找到了这个:
要想写出好的作品,需要对 Sinatra 的内部设计有所了解
扩展名。本节提供类的高级概述
和成语是 Sinatra 设计的核心。
Sinatra 有两种不同的使用模式,扩展程序应注意
的:
“经典”风格,其中应用程序在 main / the
顶级——大多数示例和文档都针对这种用法。
经典应用程序通常是单文件、独立的应用程序,它们是
直接从命令行运行或使用最小的 rackup 文件运行。什么时候
在经典应用程序中需要扩展,期望是
所有扩展功能都应该在没有额外的情况下存在
在应用程序开发人员部分设置(如包含/扩展
模块)。
“模块化”风格,其中 Sinatra::Base 被显式子类化,并且
应用程序是在子类的范围内定义的。这些
应用程序通常捆绑为库并用作组件
在更大的基于机架的系统中。模块化应用程序必须包括
通过调用 register ExtensionModule 显式地进行任何所需的扩展
在应用程序的类范围内。
大多数扩展都与这两种样式相关,但必须注意
扩展作者以确保扩展在以下情况下做正确的事情
每种风格。扩展 API(Sinatra.register 和 Sinatra.helpers)
提供以帮助扩展作者完成此任务。
重要提示:关于 Sinatra::Base 和
Sinatra::Application 仅用于后台 - 扩展
作者不需要直接修改这些类。
Sinatra::Base Sinatra::Base 类为所有
在 Sinatra 应用程序中进行评估。顶级的 DSLish 东西存在
在类范围内,而请求级的东西存在于实例范围内。
应用程序在 Sinatra::Base 的类范围内定义
子类。 “DSL”(例如,get、post、before、configure、set 等)是
只是在 Sinatra::Base 上定义的一组类方法。扩展
DSL 是通过向 Sinatra::Base 或其其中之一添加类方法来实现的
子类。但是,基类不应该用 extend 来扩展;
为此提供了 Sinatra.register 方法(如下所述)
任务。
请求在一个新的 Sinatra::Base 实例中进行评估——路由,
在过滤器、视图、帮助程序和错误页面都共享相同之前
请求级辅助方法的默认集合(例如 erb、
haml、halt、content_type 等)是定义在
Sinatra::Base 或包含在 Sinatra::Base 中的模块内。
在请求级别提供新功能是通过添加
Sinatra::Base 的实例方法。
与 DSL 扩展一样,辅助模块不应直接添加到
Sinatra::Base by extension authors with include; Sinatra.helpers
为此任务提供了方法(如下所述)。
http://www.sinatrarb.com/extensions.html