Last active
December 9, 2022 14:11
-
-
Save taichi-ishitani/4ed3cdf848ca0feb425afc2752341ca4 to your computer and use it in GitHub Desktop.
Ruby Advent Calender 2022
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'yaml' | |
require 'delegate' | |
module MyNodeExtension | |
refine Psych::Nodes::Node do | |
def mapping_key? | |
@mapping_key | |
end | |
attr_writer :mapping_key | |
end | |
end | |
using MyNodeExtension | |
class MyTreeBuilder < Psych::TreeBuilder | |
def scalar(value, anchor, tag, plain, quoted, style) | |
node = super | |
node.mapping_key = @last.mapping? && @last.children.size.odd? | |
node | |
end | |
end | |
class MyValue < SimpleDelegator | |
def initialize(value, line, column) | |
super(value) | |
@line = line | |
@column = column | |
end | |
attr_reader :line, :column | |
end | |
class MyVisitor < Psych::Visitors::ToRuby | |
def accept(node) | |
object = super | |
if node.mapping? || node.sequence? || (node.scalar? && !node.mapping_key?) | |
MyValue.new(object, node.start_line + 1, node.start_column + 1) | |
else | |
object | |
end | |
end | |
end | |
def my_yaml_load(yaml) | |
parser = Psych::Parser.new(MyTreeBuilder.new) | |
parser.parse(yaml) | |
ast = parser.handler.root.children[0] | |
visitor = MyVisitor.create | |
visitor.accept(ast) | |
end | |
yaml = <<~YAML | |
children: | |
- name: Kanta | |
age: 5 | |
- name: Kaede | |
age: 1 | |
YAML | |
obj = my_yaml_load(yaml) | |
p [obj.line, obj.column] | |
p [obj['children'].line, obj['children'].column] | |
p [obj['children'][0].line, obj['children'][0].column] | |
p [obj['children'][0]['name'].line, obj['children'][0]['name'].column] | |
p [obj['children'][0]['age'].line, obj['children'][0]['age'].column] | |
p [obj['children'][1].line, obj['children'][1].column] | |
p [obj['children'][1]['name'].line, obj['children'][1]['name'].column] | |
p [obj['children'][1]['age'].line, obj['children'][1]['age'].column] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment