简体   繁体   English

是否可以在 ruby 中为 to_yaml 指定格式选项?

[英]Is it possible to specify formatting options for to_yaml in ruby?

The code代码

require 'yaml'
puts YAML.load("
is_something:
  values: ['yes', 'no']
").to_yaml

produces产生

--- 
is_something: 
  values: 
  - "yes"
  - "no"

While this is a correct yaml, it just looks ugly when you have a hash of arrays. Is there a way for me to get to_yaml to produce the inline array version of the yaml?虽然这是一个正确的 yaml,但当您拥有 arrays 的 hash 时,它看起来很难看。我有办法让to_yaml生成 yaml 的内联数组版本吗?

An options hash can be passed to to_yaml but how do you use it?可以将选项 hash 传递给to_yaml但如何使用它?

Edit 0: Thanks Pozsár Balázs.编辑 0:感谢 Pozsár Balázs。 But, as of ruby 1.8.7 (2009-04-08 patchlevel 160), the options hash does not work as advertised.但是,从 ruby 1.8.7(2009-04-08 补丁级别 160)开始,选项 hash 并不像宣传的那样工作。 :( :(

irb
irb(main):001:0> require 'yaml'
=> true
irb(main):002:0> puts [[ 'Crispin', 'Glover' ]].to_yaml( :Indent => 4, :UseHeader => true, :UseVersion => true )
--- 
- - Crispin
  - Glover
=> nil

About the hash options: see http://yaml4r.sourceforge.net/doc/page/examples.htm关于哈希选项:参见http://yaml4r.sourceforge.net/doc/page/examples.htm

Ex.前任。 24: Using to_yaml with an options Hash 24:使用带有选项哈希的to_yaml

puts [[ 'Crispin', 'Glover' ]].to_yaml( :Indent => 4, :UseHeader => true, :UseVersion => true )
# prints:
#   --- %YAML:1.0
#   -
#       - Crispin
#       - Glover

Ex.前任。 25: Available symbols for an options Hash 25:选项哈希的可用符号

Indent : The default indentation to use when emitting (defaults to 2 ) Indent :发射时使用的默认缩进(默认为2
Separator : The default separator to use between documents (defaults to '---' ) Separator :文档之间使用的默认分隔符(默认为'---'
SortKeys : Sort Hash keys when emitting? SortKeys :发射时对哈希键进行排序? (defaults to false ) (默认为false
UseHeader : Display the YAML header when emitting? UseHeader : 发射时显示 YAML 标头? (defaults to false ) (默认为false
UseVersion : Display the YAML version when emitting? UseVersion : 发射时显示 YAML 版本? (defaults to false ) (默认为false
AnchorFormat : A formatting string for anchor IDs when emitting (defaults to ' id%03d ') AnchorFormat : 发射时锚 ID 的格式化字符串(默认为 ' id%03d ')
ExplicitTypes : Use explicit types when emitting? ExplicitTypes :发射时使用显式类型? (defaults to false ) (默认为false
BestWidth : The character width to use when folding text (defaults to 80 ) BestWidth :折叠文本时使用的字符宽度(默认为80
UseFold : Force folding of text when emitting? UseFold :发射时强制折叠文本? (defaults to false ) (默认为false
UseBlock : Force all text to be literal when emitting? UseBlock :在发射时强制所有文本都是文字吗? (defaults to false ) (默认为false
Encoding : Unicode format to encode with (defaults to :Utf8 ; requires Iconv) Encoding :要编码的 Unicode 格式(默认为:Utf8 ;需要 Iconv)

Starting from Ruby 1.9 psych is used as a default YAML engine.从 Ruby 1.9 psych被用作默认的 YAML 引擎。 It supports some attributes: http://ruby-doc.org/stdlib-2.1.0/libdoc/psych/rdoc/Psych/Handler/DumperOptions.html它支持一些属性: http : //ruby-doc.org/stdlib-2.1.0/libdoc/psych/rdoc/Psych/Handler/DumperOptions.html

So for me it works:所以对我来说它有效:

irb(main):001:0> require 'yaml'
=> true
irb(main):002:0> puts [{'a'=> 'b', 'c'=> 'd'}, {'e'=> 'f', 'g'=>'h'}].to_yaml(:indentation => 4)
---
-   a: b
    c: d
-   e: f
    g: h

This ugly hack seems to do the trick...这个丑陋的黑客似乎可以解决问题......

class Array
  def to_yaml_style
    :inline
  end
end

Browsing through ruby's source, I can't find any options I could pass to achieve the same.浏览 ruby​​ 的源代码,我找不到可以通过的任何选项来实现相同的目标。 Default options are described in thelib/yaml/constants.rb .默认选项在lib/yaml/constants.rb中描述。

Just another hack to specify the output style, but this one allows to customize it per specific object, instead of globally (eg for all arrays).只是另一种指定输出样式的技巧,但是这个方法允许根据特定对象而不是全局(例如,对于所有数组)自定义它。

https://gist.github.com/jirutka/31b1a61162e41d5064fc https://gist.github.com/jirutka/31b1a61162e41d5064fc

Simple example:简单的例子:

class Movie
  attr_accessor :genres, :actors

  # method called by psych to render YAML
  def encode_with(coder)
    # render array inline (flow style)
    coder['genres'] = StyledYAML.inline(genres) if genres
    # render in default style (block)
    coder['actors'] = actors if actors
  end
end

The latest versions of Ruby use the Psych module for YAML parsing.最新版本的 Ruby 使用 Psych 模块进行 YAML 解析。 There aren't many options that you can pass but you can change indention and line width.您可以传递的选项并不多,但您可以更改缩进和线宽。 Check the latest Psych documentation for more details.查看最新的Psych 文档以获取更多详细信息。

Use Psych directly.直接使用 Psych。

Indentation has no effect: my_yaml.to_yaml(:indentation => 2)缩进无效: my_yaml.to_yaml(:indentation => 2)

Indentation works: Psych.dump(my_yaml, :indentation => 8)缩进工程: Psych.dump(my_yaml, :indentation => 8)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM