-
Notifications
You must be signed in to change notification settings - Fork 6
Creating a translator plugin
The following is a tutorial on how to create a translator that plugs in to bel.rb. Read What are translators? to learn about what a translator is and why you might want one.
This tutorial follows the creation of a TAB-separated translator plugin for BEL Nanopubs. The example code repository is located at OpenBEL/bel.rb-translator-example. You can retrieve clone it using git:
git clone https://github.com/OpenBEL/bel.rb-translator-example
Tutorial requirements:
- Ruby installation (Version 2.0.0 or higher)
- Familiarity with the command line of your operating system
Tutorial steps:
- Create your project directory
- Describe your project as a Ruby gem
- Create a Ruby file for your translator
- Implement read functionality
- Implement write functionality
- Package your project as a Ruby gem
- Install your Ruby gem
- Test your translator in bel.rb
Your project deserves its own directory. It will group all of your project files in one place. This is also recommended for Ruby gems that are shared with others.
Create your project directory with:
mkdir "bel.rb-tsv-translator"
Recommendation The project directory is recommended as "bel.rb-[YOUR PLUGIN ID]-translator". This describes your translator as integrating with bel.rb.
This may not be suitable if your translator integrates with other libraries in addition to bel.rb.
A Ruby gem must be described with author, files provides, and required library dependencies. This is captured by a Rubygems specification.
Create the .gemspec
file in the bel.rb-tsv-translator directory using your favorite text editor. Adjust the field values to suit your needs.
You can reference the Rubygems specification when more detail is needed on a particular field.
# .gemspec
Gem::Specification.new do |s|
s.name = 'bel.rb-tsv-translator'
s.version = '0.1.0'
s.licenses = ['Apache License 2.0']
s.summary = 'A TAB-separated translator for BEL Nanopubs.'
s.description = 'This translator provides read/write functionality for BEL Nanopubs stored in TAB-separated files. This translator is intended to integrate with bel.rb.'
s.authors = ['Your Name']
s.email = 'your@email.com'
s.files = [
'lib/bel/translator/plugins/tsv.rb',
'lib/bel/translator/plugins/tsv/reader.rb',
'lib/bel/translator/plugins/tsv/writer.rb'
]
s.homepage = 'https://rubygems.org/gems/bel.rb-tsv-translator'
# Dependency on the bel.rb library.
s.add_runtime_dependency 'bel', '~> 0.5'
end
Let us make some observations here:
- The name field of your Ruby gem reflects your project directory. The Ruby gem is published with the name field.
- The homepage field is set to the location on Rubygems.org where most publicly-available Ruby gems are located.
- We include the Ruby files that are available in this gem using the files field. These files make up the TSV translator code. These Ruby files, under the lib/ directory, can be loaded into Ruby, at runtime, using require.
The translator depends on some code provides by bel.rb. We thus declare a dependency on the bel gem. The ~> 0.5 semantic version specifier says that any version greater than or equal to 0.5.0 but less than 0.6.0 is acceptable.
Note The pessimistic version specifier (known as twiddle-waka) puts trust into semantic versioning and the rigor to which the authors follow it! The OpenBEL community projects strive to follow semantic versioning.
A translator plugin must be described in order to be available to bel.rb and be presentable to a user. We do this by creating a Ruby file under the project's lib/bel/translator/plugins/ directory. This particular directory will be scanned, by the bel gem, for Ruby modules declared within the BEL::Translator::Plugins
module. Read Plugins in bel.rb more more details on how plugins are declared and loaded.
First create the lib/bel/translator/plugins directory:
# Unix
mkdir -p lib/bel/translator/plugins
# Windows
mkdir \lib\bel\translator\plugins
Then create the lib/bel/translator/plugins/tsv.rb file using your favorite text editor:
# lib/bel/translator/plugins/tsv.rb
require 'bel'
module BEL::Translator::Plugins
module Tsv
ID = :tsv
NAME = 'Tab-separated Translator'
DESCRIPTION = 'This translator provides read/write functionality for BEL Nanopubs stored in TAB-separated files. This translator is intended to integrate with bel.rb.'
MEDIA_TYPES = %i(text/tab-separated-values)
EXTENSIONS = %i(tsv tab)
def self.create_translator(options = {})
require_relative 'tsv/translator'
TsvTranslator.new
end
def self.id
ID
end
def self.name
NAME
end
def self.description
DESCRIPTION
end
def self.media_types
MEDIA_TYPES
end
def self.file_extensions
EXTENSIONS
end
end
end
Again let us make some observations here:
- We
require 'bel'
in order to define the translator plugin system. - We declare the
Tsv
module within theBEL::Translator::Plugins
module defined by the bel gem. - We define the identifier, file extensions, and media types that can be used to retrieve this translator. Read How are translators identified? for more detail on translator identifiers.
The most important Ruby method to define is create_translator
. It creates the Ruby object that provides read and write functionality.