dominikh / filesize

filesize is a small ruby class for handling filesizes with both the SI and binary prefixes, allowing conversion from any size to any other size.
MIT License
81 stars 16 forks source link

to_i does not work the same as others #16

Closed myoung34 closed 7 years ago

myoung34 commented 7 years ago

Im using this gem to sanitize user specified values.

I want whatever they have to go to 'MB'

But, i can't convert to an integer value without converting to a float then converting to an integer. is that by design?

[1] pry(#<VagrantPlugins::OVirtProvider::Config>)> @memory_size
=> "1024 MB"
[2] pry(#<VagrantPlugins::OVirtProvider::Config>)> Filesize.from(@memory_size).to_i
=> 1024000000
[3] pry(#<VagrantPlugins::OVirtProvider::Config>)> Filesize.from(@memory_size).to_i('MB')
ArgumentError: wrong number of arguments (1 for 0)
from /home/myoung/.rvm/gems/ruby-2.2.3/gems/filesize-0.1.1/lib/filesize.rb:37:in `to_i'
[4] pry(#<VagrantPlugins::OVirtProvider::Config>)> Filesize.from(@memory_size).to_f('MB')
=> 1024.0
[5] pry(#<VagrantPlugins::OVirtProvider::Config>)> Filesize.from(@memory_size).to_f('MB').to_i
=> 1024

The reason I have to do this is the API i'm integrating with requires an integer megabyte. If I provide a float, it errors.

Bringing machine 'default' up with 'ovirt4' provider...
==> default: Creating VM with the following settings...
==> default:  -- Name:          test
==> default:  -- Cluster:       Default
==> default:  -- Template:      vagrant-centos7
==> default:  -- Console Type:  vnc
==> default:  -- Memory:
==> default:  ---- Memory:      1024.0
==> default:  ---- Guaranteed:  1024.0
==> default:  -- Cpu:
==> default:  ---- Cores:       1
==> default:  ---- Sockets:     1
==> default:  ---- Threads:     1
==> default:  -- Cloud-Init:    true
Creation failed. oVirt error message was 'For correct usage, see: https://server/ovirt-engine/api/v4/model#services/vms/methods/add'
dominikh commented 7 years ago

Yes, that's by design. to_i("MB") won't make sense in the majority of cases, because you can't accurately express most sizes as an integer. That's why we're making the user go via to_f + an additional operation, to be explicit about the loss of resolution.

BTW, to_f("MB").to_i is also only correct if the size is an even multiple of an MB, or if it'd round down to one, anyway. In the other cases, you want to round, not truncate.

myoung34 commented 7 years ago

Thanks for the quick response. I'll make sure my usage is "accurate" or at least documented. That makes sense, just wanted to double check