Ruby 使全局方法在类中可访问
考虑以下Ruby 使全局方法在类中可访问,ruby,sinatra,Ruby,Sinatra,考虑以下sinatra应用程序: require 'sinatra' def f settings.development? ? 'development' : 'whatever' end class C def self.f settings.development? ? 'development' : 'whatever' end end get '/' do # f # works C.f # doesn't work
sinatra
应用程序:
require 'sinatra'
def f
settings.development? ? 'development' : 'whatever'
end
class C
def self.f
settings.development? ? 'development' : 'whatever'
end
end
get '/' do
# f # works
C.f # doesn't work, gives "NameError - undefined local variable or method `settings' for C:Class"
end
这里发生了什么?我如何使其工作?试试:
class C
def self.f
Sinatra::Application.settings.development? ? 'development' : 'whatever'
end
end
当您需要'sinatra'
时,会发生以下情况:
Sinatra::Delegator
类负责在main
对象中提供,以及get
DSL和创建Sinatra应用程序所需的所有功能。尝试:
class C
def self.f
Sinatra::Application.settings.development? ? 'development' : 'whatever'
end
end
当您需要'sinatra'
时,会发生以下情况:
Sinatra::Delegator
类负责在main
对象中提供,以及get
DSL和创建Sinatra应用程序所需的所有功能。发生的情况是,在定义新类时,您失去了对外部范围的访问,因为它为您提供了自己的范围
如上所述,要求Sinatra运行extend Sinatra::Delegator
,它添加了所有已知的方法
考虑到这一过度简化:
module A
def ping
"pong"
end
end
ping # => throws NoMethodError
extend A
ping # => "pong"
class B
def my_ping
ping
end
end
B.new.my_ping # => throws NoMethodError
为什么??因为Ruby的范围规则
您可以通过向外部范围传递引用来解决这个问题
module A
def ping
"pong"
end
end
extend A
ping # => "pong"
class B
class << self
attr_accessor :app
def my_ping
app.ping
end
end
end
B.app = self
B.my_ping # => "pong"
模块A
德平
“乒乓球”
结束
结束
延长
乒乓球
B类
“乒乓”类
发生的情况是,在定义新类时,您失去了对外部作用域的访问,因为它为您提供了自己的作用域
如上所述,要求Sinatra运行extend Sinatra::Delegator
,它添加了所有已知的方法
考虑到这一过度简化:
module A
def ping
"pong"
end
end
ping # => throws NoMethodError
extend A
ping # => "pong"
class B
def my_ping
ping
end
end
B.new.my_ping # => throws NoMethodError
为什么??因为Ruby的范围规则
您可以通过向外部范围传递引用来解决这个问题
module A
def ping
"pong"
end
end
extend A
ping # => "pong"
class B
class << self
attr_accessor :app
def my_ping
app.ping
end
end
end
B.app = self
B.my_ping # => "pong"
模块A
德平
“乒乓球”
结束
结束
延长
乒乓球
B类
“乒乓”类
或者C类
,然后在self中省略Sinatra::Application
。我认为f
也可以。但是你能解释一下这里发生了什么吗settings
是一种Sinatra::Application
的方法,对吗?为什么可以从顶级方法访问它?或者classc
,然后在self中省略Sinatra::Application
。我认为f
也可以。但是你能解释一下这里发生了什么吗settings
是一种Sinatra::Application
的方法,对吗?为什么可以从顶级方法访问它?