Float <-> String - Locale aware?
-
@jim said:
It's OK to extend only specific instances with with some instance methods, and without modifying the base class.
Called creating a singleton method.
-
@thomthom said:
Now, if only I could find a method for the other way around...
I don't think I can test the other way as my locale setting uses period as decimal point.
If your model units are metric, and your OS locale decimal separator is comma, what happens when you try to use the base class (SU extended) method String.to_l ?
Ex:
length = "5,43".to_l
(1) what does length then appear as in the console ?
(2) what does it appear as in an inputbox control ?
(3) what does it appear as in a webdialog ?What happens when:
length = "5.43".to_l
-
Why won't
"12,2".to_l.to_f
work? -
@thomthom said:
Found a nice method:
...[snip]...
Example, Norwegian locale and 1 digit precision:
Sketchup.format_degrees(500.555)
Returns the string:"~ 500,6"
What happens when:
Sketchup.format_degrees(500,555)
Wouldn't you be specifying decimals in euro-format?
When I try it there is a conflict; Ruby sees the comma as an argument delimiter, and pukes up an argument (2 for 1) exception. -
@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