imag/libimagruby
Matthias Beyer 45880b5b12 Revert the ruby build infrastructure PR.
The ruby build infrastructure PR caused our CI to get really sad, so I
revert it here.

This reverts commit

    5eaddbc6f2a4b05ac59d9e8b29d0d2226d3f2015..44e02ff8185c5ad3da6448b6caff9d2a3a9b332f
2017-02-06 15:32:23 +01:00
..
lib Revert the ruby build infrastructure PR. 2017-02-06 15:32:23 +01:00
src Impl Store::retrieve_for_module() interface function 2017-02-05 18:35:39 +01:00
test Revert the ruby build infrastructure PR. 2017-02-06 15:32:23 +01:00
.gitignore Revert the ruby build infrastructure PR. 2017-02-06 15:32:23 +01:00
Cargo.toml Add Store::new() function interface 2017-01-22 15:44:21 +01:00
Gemfile Rename: Imag -> RImag (class) 2017-01-22 18:44:47 +01:00
imag.gemspec Revert the ruby build infrastructure PR. 2017-02-06 15:32:23 +01:00
Makefile Revert the ruby build infrastructure PR. 2017-02-06 15:32:23 +01:00
Rakefile Revert the ruby build infrastructure PR. 2017-02-06 15:32:23 +01:00
README.md Update README 2017-01-25 17:30:34 +01:00

imag-ruby

A Ruby gem for scripting imag modules.

How does this work?

Well, as we have some problems with lifetimes here, we have a fairly complex codebase in this crate.

The Problem

The Problem is, that libimagstore::store::FileLockEntry<'a> has a lifetime. If we would wrap this object into a ruru wrapper and pass to the Ruby code, we couldn't guarantee anymore that the lifetime holds.

The problem is simple, you see...

The solution?

Never pass anything to the Ruby code.

Yes, exactly. The Ruby code only sees 'handles'. It never actually gets the Store object either. We move the Store Object into a Cache object (actually, the Ruby code could have multiple Store objects to work with this way) and return a StoreHandle to the Ruby code (which is a UUID underneath).

Also, the Ruby code never actually touches a FileLockEntry - it only gets a Handle for each FileLockEntry - which is a tuple of the StoreHandle and the libimagstore::storeid::StoreId for the Entry.

Each operation on a FileLockEntry is then wrapped by this very library. Each time FileLockEntry is touched, this library fetches the appropriate Store object from the static Cache, then fetches the FileLockEntry object from it, does the operation and then drops the object (which implies that the actual FileLockEntry is update()d!).

The Hell?

Yes, I know this is a lot of overhead. But what are we talking about here? This is Ruby code we're talking about here, so speed is not our concern.

You could argue this is a hell of complexity introduced in this library and yes it is. If there are bugs (and I bet there are) they would be complex as hell. But that's it... if you have a better approach, please file a PR.

Tests?

We have tests Ruby scripts in ./test, they are not executed by travis-ci, as we need Ruby 2.3.0 for this and travis has 2.2.0 as latest version. But I hope we get it in travis soonish.

Ruby gem?

This crate will contain both the Rust bindings for imag using ruru and a bunch of wrapper code for the actual imag gem.

Why another layer of indirection?

As "ruru" does not yet support modules (which is sad btw) we would end up with functions for all the things.

E.G.: imag_runtime_setup() instead of Imag::Runtime::setup()

I want to add a Ruby gem to wrap these things.

So basically a piece of Ruby which uses the Rust code to build imag as a gem which then exports a fine module system.

The module system:

Imag (Module)
  EntryContent (Class (inherits from String))
  EntryHeader (Class)
  FileLockEntryHandle (Class)
  StoreHandle (Class)
  StoreId (Class)

libimagentrytag and the other libimagentry* libraries will be pulled into this library to support more advanced operations with the FileLockEntryHandle type.