隐藏绑定中的顶级常量
Shadowing a top-level constant within a binding
我想在模板方法中隐藏 ENV
,这样如果请求的键不存在于真实的 ENV
中,我可以引发错误。显然我不想在其他地方隐藏常量 - 只是在特定方法(特定绑定)中。这可能吗?
解释器: - 我知道 Hash#fetch
的存在,而且我无时无刻不在使用它。但是,我想在生成配置文件的 ERB 模板中使用它。这个配置文件可能会被比平时更多的人接触,并不是每个人都熟悉 Ruby 为丢失的哈希键返回 nil
的行为。我还在一个系统上工作,最近,配置错误(或直接的错误配置,或对格式的误解)导致了明显的生产失败。失败是操作员错误。因此,我想建立一个约定,仅在该模板内,这将导致加薪。此外,我有一个 gem、strict_env
,它已经做到了 - 但你必须记住使用 STRICT_ENV
而不是 ENV
,并且每个 "you have to" 针对此特定工作流的声明,在这种特定情况下,对我来说是一个危险信号,因为我想要更稳健。我当然可以选择更严格的模板语言并使用该语言的逻辑来提升(例如,Mustache),但由于团队已经对 ERB 有一定的了解,并且 Rails 认可 ERB-templated-YML 作为可行的配置方法(即使你可能不同意)如果我也能坚持那个工作流程就好了。这就是为什么我想在本地更改 ENV[]
的行为。
当钥匙不存在时,您可以使用ENV.fetch(key)
来提高。
除此之外,您可以创建一个 class 并委托给 ENV,例如:
class Configuration
def self.[](key)
ENV.fetch(key)
end
end
但是从 #fetch
而不是 #[]
引发错误更像 Ruby 因为这与哈希的行为相同。
最后你可以打补丁 ENV
,但这通常不是一件好事:
def ENV.[](key)
fetch(key)
end
据我所知,您不能使用 refinements 来本地化这个猴子补丁,因为 ENV 是一个对象,而不是 class 并且它的 class 是对象。
ERB#result
采用可选绑定:
require 'erb'
class Foo
ENV = { 'RUBY_VERSION' => '1.2.3' }
def get_binding
binding
end
end
template = "Ruby version: <%= ENV['RUBY_VERSION'] %>"
ERB.new(template).result
#=> "Ruby version: 2.1.3"
b = Foo.new.get_binding
ERB.new(template).result b
#=> "Ruby version: 1.2.3"
我想在模板方法中隐藏 ENV
,这样如果请求的键不存在于真实的 ENV
中,我可以引发错误。显然我不想在其他地方隐藏常量 - 只是在特定方法(特定绑定)中。这可能吗?
解释器: - 我知道 Hash#fetch
的存在,而且我无时无刻不在使用它。但是,我想在生成配置文件的 ERB 模板中使用它。这个配置文件可能会被比平时更多的人接触,并不是每个人都熟悉 Ruby 为丢失的哈希键返回 nil
的行为。我还在一个系统上工作,最近,配置错误(或直接的错误配置,或对格式的误解)导致了明显的生产失败。失败是操作员错误。因此,我想建立一个约定,仅在该模板内,这将导致加薪。此外,我有一个 gem、strict_env
,它已经做到了 - 但你必须记住使用 STRICT_ENV
而不是 ENV
,并且每个 "you have to" 针对此特定工作流的声明,在这种特定情况下,对我来说是一个危险信号,因为我想要更稳健。我当然可以选择更严格的模板语言并使用该语言的逻辑来提升(例如,Mustache),但由于团队已经对 ERB 有一定的了解,并且 Rails 认可 ERB-templated-YML 作为可行的配置方法(即使你可能不同意)如果我也能坚持那个工作流程就好了。这就是为什么我想在本地更改 ENV[]
的行为。
当钥匙不存在时,您可以使用ENV.fetch(key)
来提高。
除此之外,您可以创建一个 class 并委托给 ENV,例如:
class Configuration
def self.[](key)
ENV.fetch(key)
end
end
但是从 #fetch
而不是 #[]
引发错误更像 Ruby 因为这与哈希的行为相同。
最后你可以打补丁 ENV
,但这通常不是一件好事:
def ENV.[](key)
fetch(key)
end
据我所知,您不能使用 refinements 来本地化这个猴子补丁,因为 ENV 是一个对象,而不是 class 并且它的 class 是对象。
ERB#result
采用可选绑定:
require 'erb'
class Foo
ENV = { 'RUBY_VERSION' => '1.2.3' }
def get_binding
binding
end
end
template = "Ruby version: <%= ENV['RUBY_VERSION'] %>"
ERB.new(template).result
#=> "Ruby version: 2.1.3"
b = Foo.new.get_binding
ERB.new(template).result b
#=> "Ruby version: 1.2.3"