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’ ?
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_".
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.
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.
# 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))
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.
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…