Feature #12960
closed[psych] new visitor class to generate custom object instead of Hash
Description
I create a patch to define new useful visitor class for Psych.
It generates custom object as mapping data instead of Hash.
Normally, you must access YAML document data like ydoc["foo"]["bar"]["baz"]
.
Using this class, you can access data like ydoc.foo.bar.baz
.
Example1: create custom object instead of Hash according to context
## define custom classes
Team = Struct.new('Team', 'name', 'members')
Member = Struct.new('Member', 'name', 'gender')
## create visitor object
require 'psych'
require 'psych/visitors/custom_class'
classmap = {
"teams" => Team,
"members" => Member,
}
visitor = Psych::Visitors::CustomClassVisitor.create(classmap)
## example YAML string
input = <<-'END'
teams:
- name: SOS Brigade
members:
- {name: Haruhi, gender: F}
- {name: Kyon, gender: M}
- {name: Mikuru, gender: F}
- {name: Itsuki, gender: M}
- {name: Yuki, gender: F}
END
## parse YAML string with creating Team or Member objects according to context
tree = Psych.parse(input)
ydoc = visitor.accept(tree)
p ydoc['teams'][0].class #=> Struct::Team
p ydoc['teams'][0]['members'][0].class #=> Struct::Member
team = ydoc['teams'][0]
p team.name #=> "SOS Brigade"
p team.members[0].name #=> "Haruhi"
p team.members[0].gender #=> "F"
Example2: create custom hash object
## allows `hash.foo` instead of `hash["foo"]`
class MagicHash < Hash
def method_missing(method, *args)
return super unless args.empty?
return self[method.to_s]
end
end
## create visitor with MagicHash
require 'psych'
require 'psych/visitors/custom_class'
classmap = {'*' => MagicHash} # '*' means default class
visitor = Psych::Visitors::CustomClassVisitor.create(classmap)
## example YAML document
input = <<-'END'
teams:
- name: SOS Brigade
members:
- {name: Haruhi, gender: F}
- {name: Kyon, gender: M}
- {name: Mikuru, gender: F}
- {name: Itsuki, gender: M}
- {name: Yuki, gender: F}
END
## parse YAML string with creating custom hash object instead of Hash
tree = Psych.parse(input)
ydoc = visitor.accept(tree)
p ydoc.class #=> MagicHash
p ydoc['teams'][0].class #=> MagicHash
p ydoc['teams'][0]['members'][0].class #=> MagicHash
p ydoc.teams[0].members[0].name #=> "Haruhi"
p ydoc.teams[0].members[0].gender #=> "F"
I believe this class is very useful, and hope it to be imported into ruby repository.
Let me know your opinion or impression.
Files
Updated by kwatch (makoto kuwata) about 8 years ago
Updated by nobu (Nobuyoshi Nakada) about 8 years ago
- Status changed from Open to Third Party's Issue
Please send to the upstream.
Updated by kwatch (makoto kuwata) about 8 years ago
Nobuyoshi Nakada wrote:
Please send to the upstream.
I understand. Thx.
(I can't find any button to close this issue. Please close this.)
Updated by duerst (Martin Dürst) about 8 years ago
makoto kuwata wrote:
(I can't find any button to close this issue. Please close this.)
The status is already "Third Party's Issue". You can think about this as a subcategory of "Closed".