Project

General

Profile

Actions

Feature #12960

closed

[psych] new visitor class to generate custom object instead of Hash

Added by kwatch (makoto kuwata) about 8 years ago. Updated about 8 years ago.

Status:
Third Party's Issue
Assignee:
-
Target version:
-
[ruby-core:78212]

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

0002-feat-psych-allow-custom-Hash-object-for-unknown-tagg.patch (781 Bytes) 0002-feat-psych-allow-custom-Hash-object-for-unknown-tagg.patch kwatch (makoto kuwata), 11/19/2016 03:21 AM
0001-feat-psych-allow-to-generate-custom-Hash-object.patch (2.04 KB) 0001-feat-psych-allow-to-generate-custom-Hash-object.patch kwatch (makoto kuwata), 11/19/2016 03:21 AM
0003-feat-psych-add-hook-point-for-mapping-key-and-value.patch (2.35 KB) 0003-feat-psych-add-hook-point-for-mapping-key-and-value.patch kwatch (makoto kuwata), 11/19/2016 03:21 AM
0004-feat-psych-add-hook-points-for-mapping-like-object.patch (2.7 KB) 0004-feat-psych-add-hook-points-for-mapping-like-object.patch kwatch (makoto kuwata), 11/19/2016 03:21 AM
0005-feat-psych-add-hook-points-for-merge.patch (1.53 KB) 0005-feat-psych-add-hook-points-for-merge.patch kwatch (makoto kuwata), 11/19/2016 03:21 AM
0006-feat-psych-refactor-hook-point-methods-for-merge.patch (883 Bytes) 0006-feat-psych-refactor-hook-point-methods-for-merge.patch kwatch (makoto kuwata), 11/19/2016 03:21 AM
0008-feat-psych-support-key-for-default-custom-class.patch (2.38 KB) 0008-feat-psych-support-key-for-default-custom-class.patch kwatch (makoto kuwata), 11/19/2016 03:21 AM
0007-feat-psych-define-Psych-Visitors-CustomClassVisitor-.patch (3.14 KB) 0007-feat-psych-define-Psych-Visitors-CustomClassVisitor-.patch kwatch (makoto kuwata), 11/19/2016 03:21 AM
0009-feat-psych-add-test-script.patch (2.7 KB) 0009-feat-psych-add-test-script.patch kwatch (makoto kuwata), 11/19/2016 03:21 AM
0010-feat-psych-add-another-test-case.patch (1.74 KB) 0010-feat-psych-add-another-test-case.patch kwatch (makoto kuwata), 11/19/2016 03:54 AM

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".

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0