Ruby中的哈希的特定值的访问方法 [英] Accessor methods for specific values of a hash in Ruby
问题描述
我正在为Ruby编写一个API包装器,用于 Omeka API。 API的一部分是在Omeka网站上创建一个表示项目的类。对API的GET请求返回一个JSON对象,我将其转换为哈希(见下文,因为它很长)。我使用递归开放结构宝石,而不是让用户浏览长字符串创建访问器方法。例如:
class OmekaItem
pre>
attr_accessor:data
def initialize (hash)
@data = RecursiveOpenStruct.new(hash,:recurse_over_arrays => true)
end
end
假设我创建了一个
item
类的实例,让用户访问数据:item.data.id
或item.data.modified
。
最重要的数据在元素texts数组中。有两种元素文本:Dublin Core和Item Type Metadata。我想为这些字段中的数据创建一个单独的Open Struct。这是我如何做的:
class OmekaItem
attr_accessor:data,:dublin_core,:item_type_metadata
def initialize(hash)
@data = RecursiveOpenStruct.new(hash,:recurse_over_arrays => true)
dublin_core = Hash.new
item_type_metadata = Hash.new
@ data.element_texts.each do | element_text |
if element_text.element_set.name ==Dublin Core
method_name = element_text.element.name.downcase.gsub(/ \s /,'_')
value = element_text。 text
dublin_core [method_name] = value
elsif element_text.element_set.name ==Item Type Metadata
method_name = element_text.element.name.downcase.gsub(/ \s /, '_')
value = element_text.text
item_type_metadata [method_name] = value
end
end
@dublin_core = RecursiveOpenStruct.new(dublin_core)
@item_type_metadata = RecursiveOpenStruct.new(item_type_metadata)
end
end
现在用户可以通过类似这样的方法调用访问Dublin Core元数据:
item.dublin_core.title
。
到目前为止很好,但这是我被困住的地方。类需要实现一个
to_h
方法返回一个带有更改数据的原始格式的哈希值,以便我可以将其传递给POST和PUT方法。如果有人要通过调用item.data.element_text [1] .text =My new data
来更改数据,那么我可以很容易地调用open返回一个散列。但是如果用户更改item.dublin_core.title =我的新标题
,该数据将与存储在@data
。如何让数据存储的两个地方排队?
项目的典型哈希值如下所示:
>> pp hash
{id=> 1,
url=>http://localhost/omeka-2.1-rc1/api/items/1,
public=> true,
featured=> false,
added=>2013-07-13T04:47:08 + 00:00,
modified=>2013-07-14T19:37:45 + 00:00,
item_type=>
{id=> 10,
url=>http://localhost/omeka-2.1-rc1/api/item_types/10,
name =>Lesson Plan,
resource=>item_types},
collection=>
{id=> 1,
url=>http://localhost/omeka-2.1-rc1/api/collections/1,
resource =>collections},
owner=>
{id=> 1,
url=>http://localhost/omeka-2.1-rc1/api/users/1,
resource =>users},
files=>
{count=> 0,
url=>http://localhost/omeka-2.1-rc1/api/files?item = 1,
resource=>files},
tags=> [],
element_texts=>
[{html=> false,
text=>Item Title,
element_set=>
{id=> 1,
url=>http://localhost/omeka-2.1-rc1/api/element_sets/1,
name =>Dublin Core,
resource=>element_sets},
element=>
{id=> 50,
url=>http://localhost/omeka-2.1-rc1/api/elements/50,
name ="Title,
resource=>elements}},
{html=> false,
text=& ,
element_set=>
{id=> 1,
url=>http://localhost/omeka-2.1-rc1/api/element_sets/1,
name =>Dublin Core,
resource=>element_sets},
element=>
{id=> 49,
url=>http://localhost/omeka-2.1-rc1/api/elements/49,
name =>主题,
resource=>元素}},
{html=> ,
element_set=>
{id=> 1,
url=>http://localhost/omeka-2.1-rc1/api/element_sets/1,
name =>Dublin Core,
resource=>element_sets},
element=>
{id=> 37,
url=>http://localhost/omeka-2.1-rc1/api/elements/37,
name =>Contributor,
resource=>elements}},
{html=> true,
text=& ,
element_set=>
{id=> 1,
url=>http://localhost/omeka-2.1-rc1/api/element_sets/1,
name =>Dublin Core,
resource=>element_sets},
element=>
{id=> 41,
url=>http://localhost/omeka-2.1-rc1/api/elements/41,
name ="Description,
resource=>elements}},
{html=> true,
text=& ,
element_set=>
{id=> 1,
url=>http://localhost/omeka-2.1-rc1/api/element_sets/1,
name =>Dublin Core,
resource=>element_sets},
element=>
{id=> 39,
url=>http://localhost/omeka-2.1-rc1/api/elements/39,
name =>创建者,
resource=>元素}},
{html=> false,
text=& ,
element_set=>
{id=> 1,
url=>http://localhost/omeka-2.1-rc1/api/element_sets/1,
name =>Dublin Core,
resource=>element_sets},
element=>
{id=> 48,
url=>http://localhost/omeka-2.1-rc1/api/elements/48,
name =>Source,
resource=>elements}},
{html=> ,
element_set=>
{id=> 1,
url=>http://localhost/omeka-2.1-rc1/api/element_sets/1,
name =>Dublin Core,
resource=>element_sets},
element=>
{id=> 45,
url=>http://localhost/omeka-2.1-rc1/api/elements/45,
name ="Publisher,
resource=>elements}},
{html=> false,
text=& ,
element_set=>
{id=> 1,
url=>http://localhost/omeka-2.1-rc1/api/element_sets/1,
name =>Dublin Core,
resource=>element_sets},
element=>
{id=> 40,
url=>http://localhost/omeka-2.1-rc1/api/elements/40,
name =>Date,
resource=>元素}},
{html=> false,
,
element_set=>
{id=> 1,
url=>http://localhost/omeka-2.1-rc1/api/element_sets/1,
name =>Dublin Core,
resource=>element_sets},
element=>
{id=> 47,
url=>http://localhost/omeka-2.1-rc1/api/elements/47,
name =Rights,
resource=>elements}},
{html=> false,
text=& ,
element_set=>
{id=> 1,
url=>http://localhost/omeka-2.1-rc1/api/element_sets/1,
name =>Dublin Core,
resource=>element_sets},
element=>
{id=> 46,
url=>http://localhost/omeka-2.1-rc1/api/elements/46,
name =>关系,
资源=>元素}},
{html=> false,
,
element_set=>
{id=> 1,
url=>http://localhost/omeka-2.1-rc1/api/element_sets/1,
name =>Dublin Core,
resource=>element_sets},
element=>
{id=> 42,
url=>http://localhost/omeka-2.1-rc1/api/elements/42,
name =>Format,
resource=>elements}},
{html=> false,
text=& ,
element_set=>
{id=> 1,
url=>http://localhost/omeka-2.1-rc1/api/element_sets/1,
name =>Dublin Core,
resource=>element_sets},
element=>
{id=> 44,
url=>http://localhost/omeka-2.1-rc1/api/elements/44,
name =>Language,
resource=>elements}},
{html=> false,
text=& ,
element_set=>
{id=> 1,
url=>http://localhost/omeka-2.1-rc1/api/element_sets/1,
name =>Dublin Core,
resource=>element_sets},
element=>
{id=> 51,
url=>http://localhost/omeka-2.1-rc1/api/elements/51,
name =>Type,
resource=>elements}},
{html=> false,
text=& ,
element_set=>
{id=> 1,
url=>http://localhost/omeka-2.1-rc1/api/element_sets/1,
name =>Dublin Core,
resource=>element_sets},
element=>
{id=> 43,
url=>http://localhost/omeka-2.1-rc1/api/elements/43,
name =>Identifier,
resource=>elements}},
{html=> false,
text=& ,
element_set=>
{id=> 1,
url=>http://localhost/omeka-2.1-rc1/api/element_sets/1,
name =>Dublin Core,
resource=>element_sets},
element=>
{id=> 38,
url=>http://localhost/omeka-2.1-rc1/api/elements/38,
name =>Coverage,
resource=>elements}},
{html=> false,
text=> ,
element_set=>
{id=> 3,
url=>http://localhost/omeka-2.1-rc1/api/element_sets/3,
name =>Item Type Metadata,
resource=>element_sets},
element=&
{id=> 11,
url=>http://localhost/omeka-2.1-rc1/api/elements/11,
name =>Duration,
resource=>elements}},
{html=> false,
text=> ,
element_set=>
{id=> 3,
url=>http://localhost/omeka-2.1-rc1/api/element_sets/3,
name =>Item Type Metadata,
resource=>element_sets},
element=>
{id=> 24,
url=>http://localhost/omeka-2.1-rc1/api/elements/24,
name =>Standards,
resource=>elements}},
{html=> false,
text=> ,
element_set=>
{id=> 3,
url=>http://localhost/omeka-2.1-rc1/api/element_sets/3,
=>Item Type Metadata,
resource=>element_sets},
element=>
{id=> 25,
url=>http://localhost/omeka-2.1-rc1/api/elements/25,
name =>Objectives,
resource=>elements}},
{html=> false,
text=> ,
element_set=>
{id=> 3,
url=>http://localhost/omeka-2.1-rc1/api/element_sets/3,
name =>Item Type Metadata,
resource=>element_sets},
element=>
{id=> 26,
url=>http://localhost/omeka-2.1-rc1/api/elements/26,
name =>Material,
resource=>elements}},
{html=> false,
text=>计划文本,
element_set=>
{id=> 3,
url=>http://localhost/omeka-2.1-rc1/api/element_sets/3,
name =>Item Type Metadata,
resource=>element_sets},
element=>
{id=> 27,
url=>http://localhost/omeka-2.1-rc1/api/elements/27,
name =>Lesson Plan Text,
resource=>elements}}],
extended_resources=> []}
解决方案这是我最后做的。它使用一些Ruby的元编程方法循环遍历元素文本,并为每个元素创建方法。两件事我不知道,真正帮助了这些。首先,使用
each_with_index
循环遍历数组,让我拥有数组中项的索引,这是创建访问器方法所必需的。第二,我学习了如何将一个值传递给proc;请参阅setter方法。class OmekaItem
attr_accessor:data
#将我们从API中获得的数据解析为方便的方法。来自API返回的JSON的所有数据
#可作为RecursiveOpenStructs
#through @data。都柏林核心和项目类型元数据字段也是
#可用,通过形式dc_title和itm_field的特殊方法。
#
#@param hash [Hash]使用来自OmekaClient :: Client :: get_hash
的哈希值
def initialize(hash)
@data = RecursiveOpenStruct。 new(hash,:recurse_over_arrays => true)
#遍历元素文本,将它们分成Dublin Core和
#项类型元数据元素。 e是元素文本散列; i是元素文本数组中element_text的
#索引。
@ data.element_texts.each_with_index do | e,i |
if e.element_set.name ==Dublin Core
#定义一个读取器方法,从这个元素中检索数据
#text @data
self.class.send (:define_method,
#方法的名称将是dc_title
e.element.name.downcase.gsub(/ ^ /,'dc _')。gsub(/ \ss /,'_'),
proc {@ data.element_texts [i] .text}
)
#定义一个setter方法,用于设置
中此元素文本的数据#@ data
self.class.send(:define_method,
#方法的名称将采用dc_title =
e.element.name.downcase.gsub(/ ^ /,'dc_')。gsub(/ \s /,'_')。gsub(/ $ /,'='),
proc {| value | @ data.element_texts [i] value}
)
elsif e.element_set.name ==Item Type Metadata
#定义一个读取器方法,从这个元素中检索数据
#text in @data
self.class.send(:define_method,
#方法的名称将具有形式itm_field
e.element.name.downcase.gsub(/ ^ /,'itm_' ).gsub(/ \s /,'_'),
proc {@ data.element_texts [i] .text}
)
#定义一个setter方法,这个元素文本在
#@ data
self.class.send(:define_method,
#方法的名称将具有形式itm_title =
e.element。 name.downcase.gsub(/ ^ /,'itm _')。gsub(/ \s /,'_')。gsub(/ $ /,'='),
proc { @ data.element_texts [i] .text = value}
)
end
end
end
end
I'm writing an API wrapper in Ruby for the Omeka API. Part of the API is making a class that represents an item on the Omeka site. A GET request to the API returns a JSON object, which I convert to a hash (see below, since it's long). Rather than making users navigate through a long hash, I'm using the Recursive Open Struct gem to create accessor methods. For example:
class OmekaItem attr_accessor :data def initialize(hash) @data = RecursiveOpenStruct.new(hash, :recurse_over_arrays => true) end end
Assuming that I've made an instance of the class called
item
that lets the user access data like so:item.data.id
oritem.data.modified
.The most important data is in the element texts array. There are two kinds of element texts: "Dublin Core" and "Item Type Metadata." I'd like to create a separate Open Struct for the data in those fields. This is how I do that:
class OmekaItem attr_accessor :data, :dublin_core, :item_type_metadata def initialize(hash) @data = RecursiveOpenStruct.new(hash, :recurse_over_arrays => true) dublin_core = Hash.new item_type_metadata = Hash.new @data.element_texts.each do |element_text| if element_text.element_set.name == "Dublin Core" method_name = element_text.element.name.downcase.gsub(/\s/, '_') value = element_text.text dublin_core[method_name] = value elsif element_text.element_set.name == "Item Type Metadata" method_name = element_text.element.name.downcase.gsub(/\s/, '_') value = element_text.text item_type_metadata[method_name] = value end end @dublin_core = RecursiveOpenStruct.new(dublin_core) @item_type_metadata = RecursiveOpenStruct.new(item_type_metadata) end end
Now users can access the Dublin Core metadata with method calls like this:
item.dublin_core.title
.So far so good, but this is where I'm stuck. The class needs to implement a
to_h
method to return a hash in the original format with changed data, so that I can pass it to POST and PUT methods. If someone were to change the data by callingitem.data.element_text[1].text = "My new data"
then I could easily call the method on the open struct that returns a hash. But if a user changesitem.dublin_core.title = "My new title"
that data will be separate from the open struct stored in@data
. How can I go about making the two places where the data is stored line up?
A typical hash for an item looks like this:
>> pp hash {"id"=>1, "url"=>"http://localhost/omeka-2.1-rc1/api/items/1", "public"=>true, "featured"=>false, "added"=>"2013-07-13T04:47:08+00:00", "modified"=>"2013-07-14T19:37:45+00:00", "item_type"=> {"id"=>10, "url"=>"http://localhost/omeka-2.1-rc1/api/item_types/10", "name"=>"Lesson Plan", "resource"=>"item_types"}, "collection"=> {"id"=>1, "url"=>"http://localhost/omeka-2.1-rc1/api/collections/1", "resource"=>"collections"}, "owner"=> {"id"=>1, "url"=>"http://localhost/omeka-2.1-rc1/api/users/1", "resource"=>"users"}, "files"=> {"count"=>0, "url"=>"http://localhost/omeka-2.1-rc1/api/files?item=1", "resource"=>"files"}, "tags"=>[], "element_texts"=> [{"html"=>false, "text"=>"Item Title", "element_set"=> {"id"=>1, "url"=>"http://localhost/omeka-2.1-rc1/api/element_sets/1", "name"=>"Dublin Core", "resource"=>"element_sets"}, "element"=> {"id"=>50, "url"=>"http://localhost/omeka-2.1-rc1/api/elements/50", "name"=>"Title", "resource"=>"elements"}}, {"html"=>false, "text"=>"Item Subject", "element_set"=> {"id"=>1, "url"=>"http://localhost/omeka-2.1-rc1/api/element_sets/1", "name"=>"Dublin Core", "resource"=>"element_sets"}, "element"=> {"id"=>49, "url"=>"http://localhost/omeka-2.1-rc1/api/elements/49", "name"=>"Subject", "resource"=>"elements"}}, {"html"=>false, "text"=>"Item Contributor", "element_set"=> {"id"=>1, "url"=>"http://localhost/omeka-2.1-rc1/api/element_sets/1", "name"=>"Dublin Core", "resource"=>"element_sets"}, "element"=> {"id"=>37, "url"=>"http://localhost/omeka-2.1-rc1/api/elements/37", "name"=>"Contributor", "resource"=>"elements"}}, {"html"=>true, "text"=>"Item Description", "element_set"=> {"id"=>1, "url"=>"http://localhost/omeka-2.1-rc1/api/element_sets/1", "name"=>"Dublin Core", "resource"=>"element_sets"}, "element"=> {"id"=>41, "url"=>"http://localhost/omeka-2.1-rc1/api/elements/41", "name"=>"Description", "resource"=>"elements"}}, {"html"=>true, "text"=>"Item Creator", "element_set"=> {"id"=>1, "url"=>"http://localhost/omeka-2.1-rc1/api/element_sets/1", "name"=>"Dublin Core", "resource"=>"element_sets"}, "element"=> {"id"=>39, "url"=>"http://localhost/omeka-2.1-rc1/api/elements/39", "name"=>"Creator", "resource"=>"elements"}}, {"html"=>false, "text"=>"Item Source", "element_set"=> {"id"=>1, "url"=>"http://localhost/omeka-2.1-rc1/api/element_sets/1", "name"=>"Dublin Core", "resource"=>"element_sets"}, "element"=> {"id"=>48, "url"=>"http://localhost/omeka-2.1-rc1/api/elements/48", "name"=>"Source", "resource"=>"elements"}}, {"html"=>false, "text"=>"Item Publisher", "element_set"=> {"id"=>1, "url"=>"http://localhost/omeka-2.1-rc1/api/element_sets/1", "name"=>"Dublin Core", "resource"=>"element_sets"}, "element"=> {"id"=>45, "url"=>"http://localhost/omeka-2.1-rc1/api/elements/45", "name"=>"Publisher", "resource"=>"elements"}}, {"html"=>false, "text"=>"Item Date", "element_set"=> {"id"=>1, "url"=>"http://localhost/omeka-2.1-rc1/api/element_sets/1", "name"=>"Dublin Core", "resource"=>"element_sets"}, "element"=> {"id"=>40, "url"=>"http://localhost/omeka-2.1-rc1/api/elements/40", "name"=>"Date", "resource"=>"elements"}}, {"html"=>false, "text"=>"Item Rights", "element_set"=> {"id"=>1, "url"=>"http://localhost/omeka-2.1-rc1/api/element_sets/1", "name"=>"Dublin Core", "resource"=>"element_sets"}, "element"=> {"id"=>47, "url"=>"http://localhost/omeka-2.1-rc1/api/elements/47", "name"=>"Rights", "resource"=>"elements"}}, {"html"=>false, "text"=>"Item Relation", "element_set"=> {"id"=>1, "url"=>"http://localhost/omeka-2.1-rc1/api/element_sets/1", "name"=>"Dublin Core", "resource"=>"element_sets"}, "element"=> {"id"=>46, "url"=>"http://localhost/omeka-2.1-rc1/api/elements/46", "name"=>"Relation", "resource"=>"elements"}}, {"html"=>false, "text"=>"Item Format", "element_set"=> {"id"=>1, "url"=>"http://localhost/omeka-2.1-rc1/api/element_sets/1", "name"=>"Dublin Core", "resource"=>"element_sets"}, "element"=> {"id"=>42, "url"=>"http://localhost/omeka-2.1-rc1/api/elements/42", "name"=>"Format", "resource"=>"elements"}}, {"html"=>false, "text"=>"Item Language", "element_set"=> {"id"=>1, "url"=>"http://localhost/omeka-2.1-rc1/api/element_sets/1", "name"=>"Dublin Core", "resource"=>"element_sets"}, "element"=> {"id"=>44, "url"=>"http://localhost/omeka-2.1-rc1/api/elements/44", "name"=>"Language", "resource"=>"elements"}}, {"html"=>false, "text"=>"Item Type", "element_set"=> {"id"=>1, "url"=>"http://localhost/omeka-2.1-rc1/api/element_sets/1", "name"=>"Dublin Core", "resource"=>"element_sets"}, "element"=> {"id"=>51, "url"=>"http://localhost/omeka-2.1-rc1/api/elements/51", "name"=>"Type", "resource"=>"elements"}}, {"html"=>false, "text"=>"Item Identifier", "element_set"=> {"id"=>1, "url"=>"http://localhost/omeka-2.1-rc1/api/element_sets/1", "name"=>"Dublin Core", "resource"=>"element_sets"}, "element"=> {"id"=>43, "url"=>"http://localhost/omeka-2.1-rc1/api/elements/43", "name"=>"Identifier", "resource"=>"elements"}}, {"html"=>false, "text"=>"Item Coverage", "element_set"=> {"id"=>1, "url"=>"http://localhost/omeka-2.1-rc1/api/element_sets/1", "name"=>"Dublin Core", "resource"=>"element_sets"}, "element"=> {"id"=>38, "url"=>"http://localhost/omeka-2.1-rc1/api/elements/38", "name"=>"Coverage", "resource"=>"elements"}}, {"html"=>false, "text"=>"Item Type Duration", "element_set"=> {"id"=>3, "url"=>"http://localhost/omeka-2.1-rc1/api/element_sets/3", "name"=>"Item Type Metadata", "resource"=>"element_sets"}, "element"=> {"id"=>11, "url"=>"http://localhost/omeka-2.1-rc1/api/elements/11", "name"=>"Duration", "resource"=>"elements"}}, {"html"=>false, "text"=>"Item Type Standards", "element_set"=> {"id"=>3, "url"=>"http://localhost/omeka-2.1-rc1/api/element_sets/3", "name"=>"Item Type Metadata", "resource"=>"element_sets"}, "element"=> {"id"=>24, "url"=>"http://localhost/omeka-2.1-rc1/api/elements/24", "name"=>"Standards", "resource"=>"elements"}}, {"html"=>false, "text"=>"Item Type Objectives", "element_set"=> {"id"=>3, "url"=>"http://localhost/omeka-2.1-rc1/api/element_sets/3", "name"=>"Item Type Metadata", "resource"=>"element_sets"}, "element"=> {"id"=>25, "url"=>"http://localhost/omeka-2.1-rc1/api/elements/25", "name"=>"Objectives", "resource"=>"elements"}}, {"html"=>false, "text"=>"Item Type Materials", "element_set"=> {"id"=>3, "url"=>"http://localhost/omeka-2.1-rc1/api/element_sets/3", "name"=>"Item Type Metadata", "resource"=>"element_sets"}, "element"=> {"id"=>26, "url"=>"http://localhost/omeka-2.1-rc1/api/elements/26", "name"=>"Materials", "resource"=>"elements"}}, {"html"=>false, "text"=>"Item Type Lesson Plan Text", "element_set"=> {"id"=>3, "url"=>"http://localhost/omeka-2.1-rc1/api/element_sets/3", "name"=>"Item Type Metadata", "resource"=>"element_sets"}, "element"=> {"id"=>27, "url"=>"http://localhost/omeka-2.1-rc1/api/elements/27", "name"=>"Lesson Plan Text", "resource"=>"elements"}}], "extended_resources"=>[]}
解决方案This is what I ended up doing. It uses some of Ruby's metaprogramming methods to loop through the element texts, and create methods for each of them. The two things I didn't know that really helped out were these. First, looping through the array with
each_with_index
lets me have the index of the item in the array, which was necessary for creating the accessor methods. Second, I learned how to pass a value to a proc; see the setter methods.class OmekaItem attr_accessor :data # Parse the data we got from the API into handy methods. All of the data # from the JSON returned by the API is available as RecursiveOpenStructs # through @data. The Dublin Core and Item Type Metadata fields are also # available though special methods of the form dc_title and itm_field. # # @param hash [Hash] Uses the hash from OmekaClient::Client::get_hash # def initialize(hash) @data = RecursiveOpenStruct.new(hash, :recurse_over_arrays => true) # Step through the element texts separating them into Dublin Core and # Item Type Metadata elements. e is the element text hash; i is the # index of the element_text in the array of element texts. @data.element_texts.each_with_index do |e, i| if e.element_set.name == "Dublin Core" # Define a reader method that retrieves the data from this element # text in @data self.class.send(:define_method, # The name of the method will have the form "dc_title" e.element.name.downcase.gsub(/^/, 'dc_').gsub(/\s/, '_'), proc{ @data.element_texts[i].text } ) # Define a setter method that sets the data for this element text in # @ data self.class.send(:define_method, # The name of the method will have the form "dc_title=" e.element.name.downcase.gsub(/^/, 'dc_').gsub(/\s/, '_').gsub(/$/, '='), proc{ |value| @data.element_texts[i].text = value } ) elsif e.element_set.name == "Item Type Metadata" # Define a reader method that retrieves the data from this element # text in @data self.class.send(:define_method, # The name of the method will have the form "itm_field" e.element.name.downcase.gsub(/^/, 'itm_').gsub(/\s/, '_'), proc{ @data.element_texts[i].text } ) # Define a setter method that sets the data for this element text in # @ data self.class.send(:define_method, # The name of the method will have the form "itm_title=" e.element.name.downcase.gsub(/^/, 'itm_').gsub(/\s/, '_').gsub(/$/, '='), proc{ |value| @data.element_texts[i].text = value } ) end end end end
这篇关于Ruby中的哈希的特定值的访问方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!