Float <-> String - Locale aware?
-
@cjthompson said:
Why won't
"12,2".to_l.to_f
work?I can't test that; it raises an:
<ArgumentError: (eval):0:in
to_l': Cannot convert "12,2" to Length>` because I think of my US-en locale settings.
TT will need to test it, with his euro settings.Of course,
"12.2".to_l.to_f
works just fine for me (and anyone in the US.) -
@dan rathbun said:
@cjthompson said:
Why won't
"12,2".to_l.to_f
work?Of course,
"12.2".to_l.to_f
works just fine for me (and anyone in the US.)I take that back.
I set Format=Decimal, Units=Millimeters, Precision=0.0000mm, and the value returned (in Inches,) is:
"12.2".to_l.to_f >> 0.480314960629921
which is a precision to 15 decimal places. [FYI: 12.7mm is considered 0.5 inches. You often see 50 caliber weapons expressed as 12.7mm] -
@dan rathbun said:
(1) what does length then appear as in the console ?
length = "5,43".to_l
0.213779527559055Because I use metric mm template it also converts the float into inches.
@dan rathbun said:
(2) what does it appear as in an inputbox control ?
Because.to_s
is called upon the Length object.@dan rathbun said:
(3) what does it appear as in a webdialog ?
You'd have to convert it to a string to pass it to a webdialog, so the result would be the same as above.
-
@dan rathbun said:
What happens when:
length = "5.43".to_l
length = "5.43".to_l Error: #<ArgumentError: (eval):894:in
to_l': Cannot convert "5.43" to Length>
(eval):894` -
@cjthompson said:
Why won't
"12,2".to_l.to_f
work?"12,2".to_l.to_f 0.480314960629921
It doesn't work because SU does unit conversion at the same time.
-
Back to the original question, then:
@thomthom said:
Is there any methods that do these conversions that are locale aware?
Are the Sketchup method extensions to the base classes, locale aware and suit your needs ??
String.to_l
Numeric.to_l -
@dan rathbun said:
Back to the original question, then:
@thomthom said:
Is there any methods that do these conversions that are locale aware?
Are the Sketchup method extensions to the base classes, locale aware and suit your needs ??
String.to_l
Numeric.to_l.to_l
andLength.to_s
is locale aware. But, it does not suit my needs. I'm trying to convert betweenString
andFloat
, not betweenString
andLength
.As mentioned before:
Sketchup.format_degrees
works forFloat
->String
It even has the extra benefit of adhering to the model unit's precision.But for
String
->Float
(where the string is formatted in the user's locale, which might include decimal separator other than a period) I only have this dirty hack:# Some locale settings uses the comma as decimal separator. .to_f does not # account for this, so all commas must be coverted to periods. def self.string_to_float(string) # Dirty hack to get the current locale's decimal separator, which is then # replaced in the string to a period which is what the .to_f method expects. @decimal_separator ||= 1.2.to_l.to_s.match(/\d(\D)\d/)[1] string.sub(@decimal_separator, '.').to_f end
-
@thomthom said:
.to_l
andLength.to_s
is locale aware. But, it does not suit my needs. I'm trying to convert betweenString
andFloat
, ... I only have this dirty hack:you could subclass class String, and not need the parameter, ie:
class FloatString < String # override to_f method (or name it .to_loc_f ) def self.to_f # insert your hack end end # class
Use:
a = FloatString.new( someString.dup ) puts a.to_f puts a.class
>> SomeModule::FloatString -
Well, how I wrap the code is one thing. But atm I'm more concerned about how I get the locale data.
It just occurred to me that might not be a good choice if one does not want the float to be truncated to the model's degree precision...
-
We can see if the user is using metric, via:
module SU_UNIT # def length_name( arg='nameString' ) # model = Sketchup.active_model manager = model.options unitopts = manager['UnitsOptions'] # # allow the ordinal in the set to be returned if arg # is any class other than String (or a String subclass.) return unitopts['LengthUnit'] unless arg.kind_of?(String) # # arg was a String, so return LengthUnit stringname unit='' # if unitopts['LengthFormat']==0 # Decimal unitSet=['Inches','Feet','Millimeters','Centimeters','Meters'] unit=unitSet[ unitopts['LengthUnit'] ] elsif unitopts['LengthFormat']==2 # Engineering unit='Feet' else # 1==Architectural, 3==Fractional unit='Inches' end # if # return unit # end # method # end # module
%(#4000BF)[EDITED: wrapped in module and method blocks.
EDIT2: replaced case statement with array subscript call.
EDIT3: corrected ordinal values for LengthFormat (they do NOT appear in dropdown control in their true order!)
EDIT4: simplfied ordinal test; renamed method] -
@thomthom said:
decimal_separator = 1.2.to_l.to_s.match(/\d(\D)\d/)[1]
This returns the decimal separator.1.23.to_s.tr!('.', decimal_separator)
And this outputs a string in the user's locale.Hacky hacky hacky...
Now: how does one do this properly?
lets try sprintf (the standard **s**tring print **f**ormatted method,) which returns a formatted String.
On your machine how does the following work?
` decplaces=6 # some integer arg or expression
sprintf("%##{decplaces}f",51.1230)the first '#' is a format flag
the second '#' is part of #{decplaces}`
-
Tried that. It's locale unaware.
The only stuff I get on Ruby and locale relates to Ruby on Rails.
-
This method only works when format is set to decimal (or engineering which is also decimal) in the model info. If fractional or architectural are used '1.2.to_l.to_s" returns '~ 1 1/4"' without any decimal separator.
Advertisement