Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

ainterface

Package Overview
Dependencies
Maintainers
1
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

ainterface

  • 1.0
  • Rubygems
  • Socket score

Version published
Maintainers
1
Created
Source
body {counter-reset: chapter; } H2:before {content: counter(chapter) ". "; counter-increment: chapter; } H2 {counter-reset: SectionH2; } H3:before {content: counter(chapter) "." counter(SectionH2) " "; counter-increment: SectionH2; } H3 {counter-reset: SectionH3; } H4:before {content: counter(chapter) "." counter(SectionH2) "." counter(SectionH3) " "; counter-increment: SectionH3; } H4 {counter-reset: SectionH4; } H5:before {content: counter(chapter) "." counter(SectionH2) "." counter(SectionH3) "." counter(SectionH4) " "; counter-increment: SectionH4; } H5 {counter-reset: SectionH5; } H6:before {content: counter(chapter) "." counter(SectionH2) "." counter(SectionH3) "." counter(SectionH4) "." counter(SectionH5) " "; counter-increment: SectionH5; } H6 {counter-reset: SectionH6; }

Interface

This Gem implements the concept of an abstract base class to Ruby.

References

This code has been heavily influenced by the code from Mark Bates (http://metabates.com/2011/02/07/building-interfaces-and-abstract-classes-in-ruby/) and James Lopez (https://github.com/bluegod/rint).

The classes provided by Mark Beates are not really "Gem ready". The AbstractInterface module referenced Bicycle. The work from James Lopez was much closer to what I wanted. The main problem I saw with his approach is that the must_implement were have to be provided in the initialize method which feels wrong and error prone. IMHO the statements should be on the module level. Hence this Gem to address this and work on the class and module level only.

Under the hood

This Gem will rewrite the new method of the class that implements an Interface and that new method will just do the normal init followed by a check if all required methods are implemented.

The new method now looks like this:

def self.new(*args, &block)
  obj = self.allocate
  obj.send :initialize, *args, &block
  obj.send :__check_interface_methods
  obj
end

where __check_interface_methods() does the actuall checking to see if the Abstract Interface has been fully implemented.

Installation

Add this line to your application's Gemfile:

gem 'ainterface'

And then execute:

$ bundle

Or install it yourself as:

$ gem install ainterface

Usage

This Gem implements the concept of an abstract interface in Ruby.

#!/usr/bin/env ruby
require 'ainterface'

# Define the abtract interface named Wheels
# Any class that implements Wheels must implement
# the methods 'number_of_wheels' and 'diameter'
module Wheels
  must_implement :number_of_wheels
  must_implement :diameter
end

# This class implments wheels.
class Car
  implements Wheels
  def number_of_wheels
    4
  end
  def diameter
    13
  end
end

car = Car.new

In the above example Car fullfills the Wheels contract and will not raise any error.

if for example the following code would have been written:

class Bicycle
  implements Wheels
  def number_of_wheels
    2
  end
end

bicycle = Bicycle.new

The following error message would have been thrown:

(eval):4:in `block in __check_interface_methods': Expected Bicycle to implement diameter for interface Wheels (AInterface::Error::NotImplementedError)
  from (eval):2:in `each'
  from (eval):2:in `__check_interface_methods'
  from (eval):4:in `new'

In the above example Wheels was a module. If desired an Interface can also be implemented as a class.

Similar to include

Any method that was defined by the Interface module is also added to the class that implements the interface

For example:

module Geometry
  must_implement :width
  must_implement :height

  def outline
    2 * width + 2 * height
  end
end

class Rectangle
  implements Geometry
  def width
    4
  end
  def height
    3
  end
end

rect = Rectangle.new
p (rect.methods - Object.methods).sort
puts "Outline = #{rect.outline}"

will product the following output:

[:height, :outline, :width]
Outline = 14

As such implements acts as an include statement.

Options

The environment variable

DISABLE_RUBY_INTERFACE=1

can be set in order to globally disable the abstract interfaces - no Error will get thrown. This might be particularly useful in production for performance reasons if we are confident enough through tests that the interfaces are all implemented.

FAQs

Package last updated on 16 Feb 2016

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc