Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Porting ruby gem to mgem

Porting ruby gem to mgem

I talked about how to port ruby gem to mgem and created a tool.

Masafumi Okura

October 15, 2022

More Decks by Masafumi Okura

Other Decks in Programming


  1. Me • Name: OKURA Masafumi • Job: Freelance software developer

    • Expertise: Ruby, Ruby on Rails, Neovim • Organizer of: Kaigi on Rails, Grow.rb, Entaku.rb, Rubygems Code Reading Meetup • Author of: Several gems including Alba (with more than 500 stars)
  2. “No”s of mruby • There’s no `require` and `require_relative` •

    There IS a mgem for `require`, but not for `require_relative` • There’s no familiar testing frameworks (MiniTest and RSpec) and tools • There IS a simple test framework • There’s no `public` and `private` • It’s actually fi ne…
  3. require and require_relative • Most of the CRuby gems depend

    heavily on `require` • In mruby, fi les are loaded by alphabetical order • If we name fi les as usual, class “A” cannot depend on class “B” (not loaded yet) • If the gem depends on `require_relative` that doesn’t work • We need some ways to avoid `require`
  4. Testing • Most of the CRuby gems use either MiniTest

    or RSpec for testing, both of which don’t work with mruby • There’s https://github.com/iij/mruby-mtest so if it uses MiniTest it might be able to convert • There’s no familiar testing tools such as FactoryBot and Faker • There’s https://github.com/okuramasafumi/mruby-factory for simple factory usecases, but not one for fake data
  5. How to convert gem to mgem • Start from “main”

    fi le, and if there’s `require` or `require_relative`, replace it with the content of the fi le • Do this process recursively • If there’s MiniTest test cases, copy each test fi les and put them into one fi le, replacing `MiniTest::Test` with `MTest::Unit::TestCase` • The fi nal result would be two large fi les: One is for production code and the other is for test code
  6. What it does • Resolve all `require_relative` into the contents

    of fi le • It does nothing about `require` • If `require_relative` is in a method, move it to the head of the fi le and resolve • Collect all MiniTest test code and put them into one test fi le
  7. How to deal with other missing things • public and

    private: simply delete them including `private_constant` • `public_send` should be replaced with `send` • ENV: simply delete it • External libraries (dependencies): Convert them into mgem recursively • It’s hard and when it hits C extension, it’s over! • We need to do these manually
  8. Seriously • We need to “bootstrap” by converting Faker and

    other testing gems into mgems • We can implement our own minimal Faker gem
  9. mruby-factory • My own re-implementation of FactoryBot • No tools

    are used, it’s just a rewrite of FactoryBot from scratch • Probably 30~40% of the features are covered • It might be enough, might not be enough
  10. Way to more mgem • Use https://github.com/okuramasafumi/gem_to_mgem to do some

    conversion for the gem you want to make into mgem • On other parts, we have to tweak manually • Sometimes it’s simply impossible • We can also write our own version from scratch