Skip to content

Instantly share code, notes, and snippets.

@taichi-ishitani
Last active December 9, 2022 14:11
Show Gist options
  • Save taichi-ishitani/4ed3cdf848ca0feb425afc2752341ca4 to your computer and use it in GitHub Desktop.
Save taichi-ishitani/4ed3cdf848ca0feb425afc2752341ca4 to your computer and use it in GitHub Desktop.
Ruby Advent Calender 2022
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