{"id":21011118,"url":"https://github.com/featurist/interfaceable","last_synced_at":"2025-05-15T03:32:07.213Z","repository":{"id":56877834,"uuid":"299655944","full_name":"featurist/interfaceable","owner":"featurist","description":"Strict interfaces in Ruby","archived":false,"fork":false,"pushed_at":"2024-04-19T14:23:34.000Z","size":76,"stargazers_count":91,"open_issues_count":0,"forks_count":2,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-05-03T18:17:42.295Z","etag":null,"topics":["ruby"],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/featurist.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-09-29T15:16:34.000Z","updated_at":"2025-03-09T05:18:31.000Z","dependencies_parsed_at":"2024-11-19T09:35:37.537Z","dependency_job_id":"8065c635-b42e-457b-ba7c-7a69399b2e3a","html_url":"https://github.com/featurist/interfaceable","commit_stats":{"total_commits":38,"total_committers":2,"mean_commits":19.0,"dds":0.4736842105263158,"last_synced_commit":"94bf2aa171cfde9a1a940497799bf68c2e5b8cb3"},"previous_names":["artemave/interfacable"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/featurist%2Finterfaceable","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/featurist%2Finterfaceable/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/featurist%2Finterfaceable/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/featurist%2Finterfaceable/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/featurist","download_url":"https://codeload.github.com/featurist/interfaceable/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254266324,"owners_count":22042086,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ruby"],"created_at":"2024-11-19T09:26:34.313Z","updated_at":"2025-05-15T03:32:06.935Z","avatar_url":"https://github.com/featurist.png","language":"Ruby","readme":"# Interfaceable [![Ruby](https://github.com/featurist/interfaceable/actions/workflows/ruby.yml/badge.svg)](https://github.com/featurist/interfaceable/actions/workflows/ruby.yml) [![Gem Version](https://badge.fury.io/rb/interfaceable.svg)](https://badge.fury.io/rb/interfaceable)\n\nImpose interfaces on classes and let this gem automatically check that the interface constraints are met.\n\n## Installation\n\nAdd this line to your application's Gemfile:\n\n```ruby\ngem 'interfaceable'\n```\n\nAnd then execute:\n\n    $ bundle install\n\n## Usage\n\nIn this example:\n\n```ruby\nmodule Carrier\n  def call(number); end\n\n  def text(number, text); end\nend\n\nclass Giffgaff\n  extend Interfaceable\n\n  implements Carrier\nend\n```\n\nAn attempt to _load_ this code will result in the following error:\n\n    Giffgaff must implement: (Interfaceable::Error)\n      - Carrier#text\n      - Carrier#call\n\nIt will keep failing until `Giffgaff` defines those methods.\n\nCorrectly! E.g.:\n\n```ruby\nclass Giffgaff\n  def call(number); end\n\n  def text(number, text = ''); end\nend\n```\n\nWill fail because of method signature mismatch:\n\n    Giffgaff must implement correctly: (Interfaceable::Error)\n      - Carrier#text:\n        - expected arguments: (req, req)\n        - actual arguments: (req, opt=)\n\nClasses may define additional optional or rest arguments.\n\n```ruby\nmodule Carrier\n  def call(number); end\n\n  def text(number, text); end\nend\n\nclass Giffgaff\n  def call(number, *opts); end\n\n  def text(number, text, opt1 = nil, opt2 = nil); end\nend\n```\n\nThis will not generate any errors since `Giffgaff` implements the required methods with correct arguments only adding new optional ones.\n\n### Rails\n\nMix in `Interfaceable` before any of the application code is loaded. For example, in the initializer. For extra peace of mind, you can noop interface checking in production:\n\n```ruby\n# config/initializers/interfaceable.rb\nclass Class\n  if Rails.env.production?\n    def implements(*args); end\n  else\n    include Interfaceable\n  end\nend\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffeaturist%2Finterfaceable","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffeaturist%2Finterfaceable","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffeaturist%2Finterfaceable/lists"}