Oj: Includes bigdecimal as a runtime dependency

Created on 21 Aug 2020  Â·  18Comments  Â·  Source: ohler55/oj

The bigdecimal gem is part of the standard Ruby API. It's included in the official Ruby distribution and its interface included in the API documentation. It's fair to assume that it's present and available.

Note however that different versions of Ruby include different versions of bigdecimal.

  • Ruby 2.7.1 comes with bigdecimal 2.0.0
  • Ruby 2.6.6 comes with bigdecimal 1.4.1
  • Ruby 2.5.8 comes with bigdecimal 1.3.4

Specifying bigdecimal as a runtime dependency pushes undue complexity on downstream projects: they are now responsible for managing the version of bigdecimal. This is especially difficult as there are breaking changes introduced in version 2.0.0. It's hard to contemplate the problems that may be introduced when using a different version of bigdecimal than the one that comes packaged with Ruby.

I don't believe it's idiomatic to specify a dependency on a gem included in the standard Ruby API. Rails doesn't specify such a dependency even though it makes use of bigdecimal.

In some environments, as described in #613, the official Ruby distribution is divided among multiple OS packages. In these cases, it's expected to install all the packages the application needs. For example, to use bigdecimal on Alpine Linux you would install the ruby-bigdecimal package.

I propose removing the runtime dependency on bigdecimal.

Most helpful comment

Glad you figured out that issue. I think that resolves the issue for all. I'll release again back to the old way but with the rubinius depends removed.

All 18 comments

Glad to have further discussion.

Was there a particular reason is was added in 3.10.9?

There was. #613 pointed out that the ruby 2.7.1 in one of the alpine images expected bigdecimal to be included in the dependencies.

Gotcha. That makes sense. I believe your latest release addresses the issue; it did for my situation. However, I'm also using RBENV and it installs the default dependencies for each Ruby version. You might need to test the other situations outlined above to make sure those work as well.

FYI: Bumping oj from 3.10.8 to 3.10.12 raises a NoMethodError: undefined method 'new' for BigDecimal:Class in one of our rails apps on boot, in shoulda-matchers 2.8.0 …/matchers/active_model/validate_inclusion_of_matcher.rb:251 under ruby 2.5.8.

Is the wrong version of bigdecimal being loaded?

Yes, this sounds like a problem with using bigdecimal 2.0 with Ruby 2.5.

A resolution would be to pin bigdecimal to 1.3.4 in the Rails app Gemfile _and_ remember to change the bigdecimal version when upgrading the app to use a new Ruby in the future.

This solution is onerous. I don't think we should push this extra work on every team using the oj gem.

Instead, if we remove oj's runtime dependency declaration for bigdecimal, downstream applications won't have bigdecimal listed in their gem bundle and they'll automatically pick up the bigdecimal version included with Ruby.

I'm happy to put in what ever works for people. The current Oj dependency is anything from 1.0 to 3. Does that force a version on Rails?

I'm with @orien on this one, i'd rather not have a gem version of the stdlib defined as a dependency. My understanding of the code is that the Bigdecimal require is a quirk for Rubinius? https://github.com/ohler55/oj/blob/f300fa5c8cb33616c8282a9fcb8d947fde947e00/lib/oj.rb#L5-L11
@ohler55 you said here that Rubinius is not supported anymore, would it make sense to remove the hard dependency to BigDecimal since I assume it's not needed?

I'll give that a try and push to the develop branch. If interested parties can try it that would be helpful.

Removed and pushed.

I just update my Gemfile with gem 'oj', git: 'https://github.com/ohler55/oj.git', branch: 'develop' then ran bundle update. It removed references in the gemfile.lock :

DELETED

bigdecimal (2.0.0)

oj (3.10.12)
      bigdecimal (>= 1.0, < 3)

Ran rspec tests... everything passed without a hitch, using Rails 6.0.3.2, Ruby 2.7.1, RBENV.

Being the one who started the discussion, I realized, that this might be rather a problem of mine, using the incorrect alpine package.

In alpine, there is ruby which is the bare minimum, not including the standard libraries. Then again, there is ruby-full, which is a meta package, that includes ruby plus the packages covering the standard library. This was a bit counter-intuitive for me, as I would have expected a package ruby to cover the full standard library.

Using ruby-full in alpine works for my use case and would make requiring bigdecimal not necessary. If it should be required still is another point. I do not see any harm in it being required. At least not without version. Requiring it with a specific version might indeed cause a breakup for gems, that require both, oj and a specific version of bigdecimal, as mentioned by several others here.

Related discussion see https://github.com/simplecov-ruby/simplecov/issues/917

Glad you figured out that issue. I think that resolves the issue for all. I'll release again back to the old way but with the rubinius depends removed.

Released

Can this be closed?

Can this be closed?

I believe so. I haven't had any issues since the last release.

Thanks all. I appreciate the discussion.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

hhff picture hhff  Â·  14Comments

dgollahon picture dgollahon  Â·  5Comments

mediafinger picture mediafinger  Â·  40Comments

gerrywastaken picture gerrywastaken  Â·  36Comments

Asmoddym picture Asmoddym  Â·  6Comments