通过 ruby 中的方法输出散列中键的值
Output value of keys in hash by method in ruby
我在 ruby 上写了奇怪的、小的和简单的 DSL,我坚持键的输出值。
我需要通过该命令输出散列的具体键的值:
p config.key1
#> Output down below:
#> "value1"
# here's key1 is key of hash, i want to output value of key that i wrote in method call.
# p config.key_name for example
这是我的配置实现:
require "deep_merge/rails_compat"
class Configus
class InHash
attr_reader :inner_hash
def initialize
@inner_hash = {}
end
def method_missing(name, *args, &block)
if block_given?
context = InHash.new
context.instance_eval &block
result = context.inner_hash
else
result = args
end
@inner_hash[name] = result
end
end
def self.config(environment, parent = nil, &block)
in_hash = InHash.new
in_hash.instance_eval &block
keys = in_hash.inner_hash.keys
index = keys.find_index(environment)
if parent && environment
parent_hash = in_hash.inner_hash[parent]
adopted_hash = in_hash.inner_hash[environment]
merged_hash = parent_hash.deeper_merge!(adopted_hash, { :overwrite_arrays => "TRUE" })
elsif environment == keys[index]
"#{environment.capitalize} hash: " + in_hash.inner_hash[environment]
end
end
end
这是我的 init.rb:
require "./configus"
require "pry"
config = Configus.config :staging, :production do
production do
key1 "value1"
key2 "value2"
group1 do
key3 "value3"
key4 "value4"
end
end
staging do
key2 "new value2"
group1 do
key4 "new value4"
end
end
development do
key1 "new value1"
key2 "value2"
group1 do
key3 "new value3"
key4 "value4"
end
end
productionisgsgsd do
key10 "value10"
end
end
puts config.key1
#> I wrote output down below:
Traceback (most recent call last):
init.rb:35:in `<main>': undefined method `key1' for #<Hash:0x000056261379cdb0> (NoMethodError)
Did you mean? key
key?
keys
我只想用具体的命令输出散列的具体键的值:
p config.key_name
但我不知道该怎么做,因为我的愚蠢问题,我想问问你们。
P.S对不起我的英语水平和dsl的奇怪实现¯\_(ツ)_/¯
问题是您 return 来自 Configus.config
方法的普通散列。相反,您应该 return 您可以自定义行为的特殊 InHash
实例。
当前问题在这里:
def self.config(environment, parent = nil, &block)
in_hash = InHash.new
in_hash.instance_eval &block
keys = in_hash.inner_hash.keys
index = keys.find_index(environment)
if parent && environment
parent_hash = in_hash.inner_hash[parent]
adopted_hash = in_hash.inner_hash[environment]
merged_hash = parent_hash.deeper_merge!(adopted_hash, { :overwrite_arrays => "TRUE" })
# ^ the above line returns a normal hash from the method
in_hash # <= add this to return your in_hash object
elsif environment == keys[index]
"#{environment.capitalize} hash: " + in_hash.inner_hash[environment]
end
end
上面的问题并没有完全解决,因为现在return是你的InHash
实例,但是你的InHash
没有办法获取密钥,你只能设置他们。所以你想添加一种获取值的方法:
def method_missing(name, *args, &block)
if block_given?
context = InHash.new
context.instance_eval &block
@inner_hash[name] = context # set to the nested InHash instance
elsif args.empty?
@inner_hash[name] # without arguments given read the value
else
@inner_hash[name] = args # set to the arguments provided
end
end
以下代码:
config = Configus.config :staging, :production do
# ...
end
现在应该将 config
设置为一个 InHash
实例,它定义了您的自定义行为。如果没有给出进一步的参数,method_missing
中的 args.empty?
签入将 return 一个值。意思是:
config.key1
现在应该 return 你的 ["value1"]
值。 @inner_hash[name] = args
将始终将值设置为数组。如果你不想要这个,你可能想把它改成:
@inner_hash[name] = args.size > 1 ? args : args.first
我在 ruby 上写了奇怪的、小的和简单的 DSL,我坚持键的输出值。 我需要通过该命令输出散列的具体键的值:
p config.key1
#> Output down below:
#> "value1"
# here's key1 is key of hash, i want to output value of key that i wrote in method call.
# p config.key_name for example
这是我的配置实现:
require "deep_merge/rails_compat"
class Configus
class InHash
attr_reader :inner_hash
def initialize
@inner_hash = {}
end
def method_missing(name, *args, &block)
if block_given?
context = InHash.new
context.instance_eval &block
result = context.inner_hash
else
result = args
end
@inner_hash[name] = result
end
end
def self.config(environment, parent = nil, &block)
in_hash = InHash.new
in_hash.instance_eval &block
keys = in_hash.inner_hash.keys
index = keys.find_index(environment)
if parent && environment
parent_hash = in_hash.inner_hash[parent]
adopted_hash = in_hash.inner_hash[environment]
merged_hash = parent_hash.deeper_merge!(adopted_hash, { :overwrite_arrays => "TRUE" })
elsif environment == keys[index]
"#{environment.capitalize} hash: " + in_hash.inner_hash[environment]
end
end
end
这是我的 init.rb:
require "./configus"
require "pry"
config = Configus.config :staging, :production do
production do
key1 "value1"
key2 "value2"
group1 do
key3 "value3"
key4 "value4"
end
end
staging do
key2 "new value2"
group1 do
key4 "new value4"
end
end
development do
key1 "new value1"
key2 "value2"
group1 do
key3 "new value3"
key4 "value4"
end
end
productionisgsgsd do
key10 "value10"
end
end
puts config.key1
#> I wrote output down below:
Traceback (most recent call last):
init.rb:35:in `<main>': undefined method `key1' for #<Hash:0x000056261379cdb0> (NoMethodError)
Did you mean? key
key?
keys
我只想用具体的命令输出散列的具体键的值: p config.key_name 但我不知道该怎么做,因为我的愚蠢问题,我想问问你们。
P.S对不起我的英语水平和dsl的奇怪实现¯\_(ツ)_/¯
问题是您 return 来自 Configus.config
方法的普通散列。相反,您应该 return 您可以自定义行为的特殊 InHash
实例。
当前问题在这里:
def self.config(environment, parent = nil, &block)
in_hash = InHash.new
in_hash.instance_eval &block
keys = in_hash.inner_hash.keys
index = keys.find_index(environment)
if parent && environment
parent_hash = in_hash.inner_hash[parent]
adopted_hash = in_hash.inner_hash[environment]
merged_hash = parent_hash.deeper_merge!(adopted_hash, { :overwrite_arrays => "TRUE" })
# ^ the above line returns a normal hash from the method
in_hash # <= add this to return your in_hash object
elsif environment == keys[index]
"#{environment.capitalize} hash: " + in_hash.inner_hash[environment]
end
end
上面的问题并没有完全解决,因为现在return是你的InHash
实例,但是你的InHash
没有办法获取密钥,你只能设置他们。所以你想添加一种获取值的方法:
def method_missing(name, *args, &block)
if block_given?
context = InHash.new
context.instance_eval &block
@inner_hash[name] = context # set to the nested InHash instance
elsif args.empty?
@inner_hash[name] # without arguments given read the value
else
@inner_hash[name] = args # set to the arguments provided
end
end
以下代码:
config = Configus.config :staging, :production do
# ...
end
现在应该将 config
设置为一个 InHash
实例,它定义了您的自定义行为。如果没有给出进一步的参数,method_missing
中的 args.empty?
签入将 return 一个值。意思是:
config.key1
现在应该 return 你的 ["value1"]
值。 @inner_hash[name] = args
将始终将值设置为数组。如果你不想要这个,你可能想把它改成:
@inner_hash[name] = args.size > 1 ? args : args.first