Error YAML::dump

Hi folks,
I am running a plugin that stores data in a file using YAML::dump. All works fine in 2020, but in 2021 in encpounter this error (see example below)
For as far as i researched, this only happens on strings that start with numbers and end on underscores. Anyone encountered this and does anyone have any tips to work around this ‘new feature’ ?

YAML::dump("71")  =>  --- '71'
YAML::dump("71_")  =>  Error: #<ArgumentError: invalid value for Integer(): "71_">
.../psych/scalar_scanner.rb:104:in `Integer'
.../psych/scalar_scanner.rb:104:in `parse_int'
.../psych/scalar_scanner.rb:95:in `tokenize'
.../psych/visitors/yaml_tree.rb:279:in `visit_String'
.../psych/visitors/yaml_tree.rb:136:in `accept'
.../psych/visitors/yaml_tree.rb:118:in `push'
.../RubyStdLib/psych.rb:513:in `dump'

Presumable this is stricter YAML parsing in Ruby 2.7 (SU2021) vs Ruby 2.5 (SU2019/SU2020)

Looks like you can address this by making sure the string you pass is a quoted string.

YAML::dump("\"71_\"")

When you call YAML::dump("71_") the YAML string is: 71_. Which starts off numeric, but suddenly ends up with an underscore. If what you are passing in is a string the safe thing is to quote it: "71_".

1 Like

Thanks, that was the solution. Not needed in SU2020, but very much needed in SU2021!

This works for single values like YAML::dump("\“71_\”")
The value im dumping is a hash like : YAML::dump({“number1”=>“10”, “number2”=>“123__”})
Any tips there? This works flawless in SU2020, but gives an error in 2021

YAML::dump({“number1”=>“10”, “number2”=>“123__”})
SU2020 result : — number1: ‘10’ number2: ‘123__’

Su2021 result : Error: #<ArgumentError: invalid value for Integer(): “123__”>

Checking all values in the hash is not really an option, since the structure of my hashes are not fixed.

I understand the explanation but a string like 71__c works flawless. It seems to only be an issue with strings that consist of any combination of numbers and underscores, while starting with a number. To me this seems like a flaw in the DUMP method and not a flaw in my code.

Yea, seem to be a bug in Ruby 2.7.x: https://bugs.ruby-lang.org/issues/17556

You might want to search around in Ruby forums for workarounds.

Great!, thanks for the feedback

Let us know if you find one.

From that Ruby bug tracker it wasn’t clear if they’ve released a Ruby version with the fix yet…

FWIW, The problem was in the Psych Gem.

Merge pull request #438 from mthorn/master
Fix ArgumentError with leading and trailing underscores in number str…

Thanks!
Any idea for a work around, other than rewriting my hashes or waiting till SU updates the ruby version?

Problem is that this is part of the stdlib Psych module. An extension developer cannot just patch that because it’s shipping with SketchUp and not under control of extension developers.

Not seeing an immediate easy way for extension devs to deal with the bugged Ruby 2.7 versions…

Will have to look into this after the holidays, I’m signing off now, and most of the SketchUp team will so soon as well. See you all after the new year.

I would suggest abandon YAML for JSON files.

# Where Opts is a local constant referencing a hash of plugin options
require 'json'

# Write out the options:
opts_json = Opts.to_json
filepath = File.join(__dir__,'options.json')
IO.write(filepath, opts_json)

# Load the options:
filepath = File.join(__dir__,'options.json')
opts_json = IO.read(filepath)
Opts.merge!(JSON.parse(opts_json))

REF: Module: JSON (Ruby 2.7.2)

NOTE: If you want “pretty” readable output .json files, then use JSON.pretty_generate() instead of the plain Jane to_json

opts_json = JSON.pretty_generate(Opts)

Here is old topic where I posted a set of methods to control options …

Storing Plugin Data Revisited (Wall Presets) - #19 by DanRathbun

Peewee, As a temporary fix, drop this file into your Plugins folder. It simply replaces the faulty method with one that is correct. (I hope)

SW_psych_underscores_patch.rb (241 Bytes)

1 Like

He guys,
Greatly appreciate all the suggestions! Thanks for helping out.
Have a great holidays.

This really should be part of his extension distribution (if they go with YAML.)

Works like a charm., thanx

Is this something that is intended to be distributed to other users? Or is this only for yourself? Accepting extensions on EW that patches the APIs would be an issue to manage, if multiple extensions tries to apply patches to the system.

I would like to second Dan’s suggestion, that if possible (you have no external factor that force YAML) then JSON would be preferable.

1 Like

I haven’t worked with them for a while, but Ruby ‘Refinements’ should allow you to patch the file without affecting other plugins…

3 Likes

That is probably the only scenario were I’d agree on refinements being appropriate. :+1:

As long as we’re on Ruby issues, String#tr is often faster than String#gsub when performing single character replacements, so…

Integer(string.tr(',_', '')

I don’t think refinements are used frequently, but if one needs to use an older (and possibly unsupported) gem along with newer gems, they may be the only option.

The same kind of problem can happen with the Rubies shipped with SU. With stand alone Ruby, updating a stdlib or bundled gem is common, but can’t be done easily with SU…

1 Like