Class: Sycl::Array
- Inherits:
-
Array
- Object
- Array
- Sycl::Array
- Defined in:
- lib/sycl.rb
Overview
A Sycl::Array is like an Array, but creating one from an array blesses any child Array or Hash objects into Sycl::Array or Sycl::Hash objects. All the normal Array methods are supported, and automatically promote any inputs into Sycl equivalents. The following example illustrates this:
h = { 'a' => { 'b' => 'Hello, world!' } }
a = Sycl::Array.new
a << h
puts a.first.a.b # outputs 'Hello, world!'
A Sycl::Array supports YAML preprocessing and postprocessing, and having individual nodes marked as being rendered in inline style. YAML output is always sorted, unless individual nodes are marked as being rendered unsorted.
a = Sycl::Array.from_array %w{bravo delta charlie alpha}
a.render_inline!
a.yaml_preprocessor { |x| x.each { |e| e.capitalize! } }
a.yaml_postprocessor { |yaml| yaml.sub(/\A---\s+/, '') }
puts a.first # outputs 'bravo'
puts a.to_yaml # outputs '[Alpha, Bravo, Charlie, Delta]'
Defined Under Namespace
Classes: MockNativeType
Constant Summary collapse
- @@default_sorting =
true
Class Method Summary collapse
-
.[](*args) ⇒ Object
:nodoc:.
-
.default_sorting=(sort) ⇒ Object
Set Default Array Sorting.
-
.from_array(array) ⇒ Object
Create a Sycl::Array from a normal Array, or, really, any object that supports Enumerable#each().
-
.load_file(filename) ⇒ Object
Like Sycl::load_file(), a shortcut method to create a Sycl::Array from loading and parsing YAML from a file.
Instance Method Summary collapse
-
#<<(e) ⇒ Object
:nodoc:.
-
#[]=(*args) ⇒ Object
Make sure that if we write to this array, we promote any inputs to their Sycl equivalents.
-
#collect!(&block) ⇒ Object
:nodoc:.
-
#concat(a) ⇒ Object
:nodoc:.
-
#encode_with(coder) ⇒ Object
:nodoc:.
-
#fill(*args, &block) ⇒ Object
:nodoc:.
-
#initialize(*args) ⇒ Array
constructor
:nodoc:.
-
#insert(i, *args) ⇒ Object
:nodoc:.
-
#map!(&block) ⇒ Object
:nodoc:.
-
#method(sym) ⇒ Object
:nodoc:.
-
#push(*args) ⇒ Object
:nodoc:.
-
#render_inline! ⇒ Object
Make this array, and its children, rendered in inline/flow style.
-
#render_sorted! ⇒ Object
Sort this array when it is rendered as YAML.
-
#render_unsorted! ⇒ Object
Do not sort this array when it is rendered as YAML.
-
#render_values_inline! ⇒ Object
Keep rendering this array in block (multi-line) style, but, make this array’s children rendered in inline/flow style.
-
#replace(a) ⇒ Object
:nodoc:.
-
#to_yaml(opts = {}) ⇒ Object
Render this object as YAML.
-
#unshift(*args) ⇒ Object
:nodoc:.
-
#yaml_postprocess(yaml) ⇒ Object
:nodoc:.
-
#yaml_postprocessor(&block) ⇒ Object
Set a postprocessor hook which runs after YML is dumped, for example, via to_yaml() or Sycl::dump().
-
#yaml_preprocess! ⇒ Object
:nodoc:.
-
#yaml_preprocessor(&block) ⇒ Object
Set a preprocessor hook which runs before each time YAML is dumped, for example, via to_yaml() or Sycl::dump().
Constructor Details
#initialize(*args) ⇒ Array
:nodoc:
134 135 136 137 138 139 140 |
# File 'lib/sycl.rb', line 134 def initialize(*args) # :nodoc: @yaml_preprocessor = nil @yaml_postprocessor = nil @yaml_style = nil @render_sorted = @@default_sorting super end |
Class Method Details
.[](*args) ⇒ Object
:nodoc:
142 143 144 |
# File 'lib/sycl.rb', line 142 def self.[](*args) # :nodoc: Sycl::Array.from_array super end |
.default_sorting=(sort) ⇒ Object
170 171 172 |
# File 'lib/sycl.rb', line 170 def self.default_sorting=(sort) @@default_sorting = sort end |
.from_array(array) ⇒ Object
Create a Sycl::Array from a normal Array, or, really, any object that supports Enumerable#each(). Every child Array or Hash gets promoted to a Sycl::Array or Sycl::Hash.
157 158 159 160 161 |
# File 'lib/sycl.rb', line 157 def self.from_array(array) # :nodoc: retval = Sycl::Array.new array.each { |e| retval << Sycl::from_object(e) } retval end |
.load_file(filename) ⇒ Object
Like Sycl::load_file(), a shortcut method to create a Sycl::Array from loading and parsing YAML from a file.
149 150 151 |
# File 'lib/sycl.rb', line 149 def self.load_file(filename) Sycl::Array.from_array YAML::load_file filename end |
Instance Method Details
#<<(e) ⇒ Object
:nodoc:
187 188 189 190 191 192 |
# File 'lib/sycl.rb', line 187 def <<(e) # :nodoc: unless e.is_a?(Sycl::Hash) || e.is_a?(Sycl::Array) e = Sycl::from_object(e) end super end |
#[]=(*args) ⇒ Object
Make sure that if we write to this array, we promote any inputs to their Sycl equivalents. This lets dot notation, styled YAML, and other Sycl goodies continue.
179 180 181 182 183 184 185 |
# File 'lib/sycl.rb', line 179 def []=(*args) # :nodoc: raise ArgumentError => 'wrong number of arguments' unless args.size > 1 unless args[-1].is_a?(Sycl::Hash) || args[-1].is_a?(Sycl::Array) args[-1] = Sycl::from_object(args[-1]) end super end |
#collect!(&block) ⇒ Object
:nodoc:
194 195 196 |
# File 'lib/sycl.rb', line 194 def collect!(&block) # :nodoc: super { |o| Sycl::from_object(block.call o) } end |
#concat(a) ⇒ Object
:nodoc:
202 203 204 205 |
# File 'lib/sycl.rb', line 202 def concat(a) # :nodoc: a = Sycl::Array.from_array(a) unless a.is_a?(Sycl::Array) super end |
#encode_with(coder) ⇒ Object
:nodoc:
393 394 395 396 |
# File 'lib/sycl.rb', line 393 def encode_with(coder) # :nodoc: coder.style = Psych::Nodes::Sequence::FLOW if @yaml_style == :inline coder.represent_seq nil, sort end |
#fill(*args, &block) ⇒ Object
:nodoc:
207 208 209 210 211 212 213 214 215 216 217 |
# File 'lib/sycl.rb', line 207 def fill(*args, &block) # :nodoc: raise ArgumentError => 'wrong number of arguments' if args.empty? if block_given? super { |idx| Sycl::from_object(block.call idx) } else unless args[0].is_a?(Sycl::Hash) || args[0].is_a?(Sycl::Array) args[0] = Sycl::from_object(args[0]) end super end end |
#insert(i, *args) ⇒ Object
:nodoc:
219 220 221 222 223 224 225 226 227 |
# File 'lib/sycl.rb', line 219 def insert(i, *args) # :nodoc: raise ArgumentError => 'wrong number of arguments' if args.empty? args.collect! do |o| unless o.is_a?(Sycl::Hash) || o.is_a?(Sycl::Array) o = Sycl::from_object(o) end end super end |
#map!(&block) ⇒ Object
:nodoc:
198 199 200 |
# File 'lib/sycl.rb', line 198 def map!(&block) # :nodoc: super { |o| Sycl::from_object(block.call o) } end |
#method(sym) ⇒ Object
:nodoc:
356 357 358 |
# File 'lib/sycl.rb', line 356 def method(sym) # :nodoc: sym == :to_yaml ? MockNativeType.new : super end |
#push(*args) ⇒ Object
:nodoc:
229 230 231 232 233 234 235 236 237 |
# File 'lib/sycl.rb', line 229 def push(*args) # :nodoc: raise ArgumentError => 'wrong number of arguments' if args.empty? args.collect! do |o| unless o.is_a?(Sycl::Hash) || o.is_a?(Sycl::Array) o = Sycl::from_object(o) end end super end |
#render_inline! ⇒ Object
Make this array, and its children, rendered in inline/flow style. The default is to render arrays in block (multi-line) style.
Example:
a = Sycl::Array::from_array %w{one two}
a.yaml_postprocessor { |yaml| yaml.sub(/\A---\s+/, '') }
puts a.to_yaml # output: "- one\n- two"
a.render_inline!
puts a.to_yaml # output: '[one, two]'
267 268 269 |
# File 'lib/sycl.rb', line 267 def render_inline! @yaml_style = :inline end |
#render_sorted! ⇒ Object
Sort this array when it is rendered as YAML. Useful when the default_sorting has been set to false and arrays should be sorted.
302 303 304 |
# File 'lib/sycl.rb', line 302 def render_sorted! @render_sorted = true end |
#render_unsorted! ⇒ Object
Do not sort this array when it is rendered as YAML. Usually we want elements sorted so that diffs are human-readable, however, there are certain cases where array ordering is significant (for example, a sorted list of queues).
295 296 297 |
# File 'lib/sycl.rb', line 295 def render_unsorted! @render_sorted = false end |
#render_values_inline! ⇒ Object
Keep rendering this array in block (multi-line) style, but, make this array’s children rendered in inline/flow style.
Example:
a = Sycl::Array::from_array ['one', {'two' => ['three']}]
a.yaml_postprocessor { |yaml| yaml.sub(/\A---\s+/, '') }
a.render_values_inline!
puts a.to_yaml # output: "- one\n- two: [three]"
a.render_inline!
puts a.to_yaml # output: '[one, {two: [three]}]'
284 285 286 287 288 |
# File 'lib/sycl.rb', line 284 def render_values_inline! self.each do |e| e.render_inline! if e.respond_to?(:render_inline!) end end |
#replace(a) ⇒ Object
:nodoc:
239 240 241 242 |
# File 'lib/sycl.rb', line 239 def replace(a) # :nodoc: a = Sycl::Array.from_array(a) unless a.is_a?(Sycl::Array) super end |
#to_yaml(opts = {}) ⇒ Object
Render this object as YAML. Before rendering, run the object through any yaml_preprocessor() code block. After rendering, filter the YAML text through any yaml_postprocessor() code block.
Nodes marked with render_inline!() or render_values_inline!() will be output in flow/inline style, all hashes and arrays will be sorted, and we set a long line width to more or less support line wrap under the Psych library.
370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 |
# File 'lib/sycl.rb', line 370 def to_yaml(opts = {}) yaml_preprocess! if defined?(YAML::ENGINE) && YAML::ENGINE.yamler == 'psych' opts ||= {} opts[:line_width] ||= 999999 # Psych doesn't let you disable line wrap yaml = super else yaml = YAML::quick_emit(self, opts) do |out| if @render_sorted out.seq(nil, @yaml_style || to_yaml_style) do |seq| sort.each { |e| seq.add(e) } end else out.seq(nil, @yaml_style || to_yaml_style) do |seq| each { |e| seq.add(e) } end end end end yaml_postprocess yaml end |
#unshift(*args) ⇒ Object
:nodoc:
244 245 246 247 248 249 250 251 252 |
# File 'lib/sycl.rb', line 244 def unshift(*args) # :nodoc: raise ArgumentError => 'wrong number of arguments' if args.empty? args.collect! do |o| unless o.is_a?(Sycl::Hash) || o.is_a?(Sycl::Array) o = Sycl::from_object(o) end end super end |
#yaml_postprocess(yaml) ⇒ Object
:nodoc:
341 342 343 |
# File 'lib/sycl.rb', line 341 def yaml_postprocess(yaml) # :nodoc: @yaml_postprocessor ? @yaml_postprocessor.call(yaml) : yaml end |
#yaml_postprocessor(&block) ⇒ Object
Set a postprocessor hook which runs after YML is dumped, for example, via to_yaml() or Sycl::dump(). The hook is a block that gets the YAML text string as an argument, and returns a new, possibly different, YAML text string.
A common example use case is to suppress the initial document separator, which is just visual noise when humans are viewing or editing a single YAML file:
a.yaml_postprocessor { |yaml| yaml.sub(/\A---\s+/, '') }
Your conventions might also prohibit trailing whitespace, which at least the Syck library will tack on the end of YAML hash keys:
a.yaml_postprocessor { |yaml| yaml.gsub(/:\s+$/, '') }
333 334 335 |
# File 'lib/sycl.rb', line 333 def yaml_postprocessor(&block) @yaml_postprocessor = block if block_given? end |
#yaml_preprocess! ⇒ Object
:nodoc:
337 338 339 |
# File 'lib/sycl.rb', line 337 def yaml_preprocess! # :nodoc: @yaml_preprocessor.call(self) if @yaml_preprocessor end |
#yaml_preprocessor(&block) ⇒ Object
Set a preprocessor hook which runs before each time YAML is dumped, for example, via to_yaml() or Sycl::dump(). The hook is a block that gets the object itself as an argument. The hook can then set render_inline!() or similar style arguments, prune nil or empty leaf values from hashes, or do whatever other styling needs to be done before a Sycl object is rendered as YAML.
313 314 315 |
# File 'lib/sycl.rb', line 313 def yaml_preprocessor(&block) @yaml_preprocessor = block if block_given? end |