{"id":19063243,"url":"https://github.com/delner/hollerback","last_synced_at":"2025-07-09T14:09:11.594Z","repository":{"id":56876576,"uuid":"56740317","full_name":"delner/hollerback","owner":"delner","description":"Simple DSL-like callback pattern for Ruby.","archived":false,"fork":false,"pushed_at":"2016-05-21T18:33:05.000Z","size":10,"stargazers_count":8,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-06-30T06:04:15.284Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/delner.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}},"created_at":"2016-04-21T03:41:07.000Z","updated_at":"2021-06-25T12:23:44.000Z","dependencies_parsed_at":"2022-08-20T22:00:40.350Z","dependency_job_id":null,"html_url":"https://github.com/delner/hollerback","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/delner/hollerback","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/delner%2Fhollerback","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/delner%2Fhollerback/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/delner%2Fhollerback/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/delner%2Fhollerback/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/delner","download_url":"https://codeload.github.com/delner/hollerback/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/delner%2Fhollerback/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264473885,"owners_count":23613960,"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":[],"created_at":"2024-11-09T00:29:22.485Z","updated_at":"2025-07-09T14:09:11.579Z","avatar_url":"https://github.com/delner.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"Hollerback\n==========\n\n[![Build Status](https://travis-ci.org/delner/hollerback.svg?branch=master)](https://travis-ci.org/delner/hollerback) ![Gem Version](https://img.shields.io/gem/v/hollerback.svg?maxAge=2592000)\n###### *For Ruby 2+*\n\n### Introduction\n\nHollerback adds the callback pattern to your application, allowing you to easily implement DSL-like event handling to your application.\n\n```ruby\nnote = NoteApi.get_note(\"Grocery List\") do |on|\n  on.found do |note|\n    puts \"Found an existing note!\"\n  end\n  on.not_found do |name|\n    puts \"Note is missing! Creating a new one.\"\n    Note.create!(name: name)\n  end\n  on.error do |error|\n    puts \"Failed to retrieve note!\"\n  end\nend\n```\n\n### Installation\n\n##### If you're not using Bundler...\n\nInstall the gem via:\n\n```\ngem install hollerback\n```\n\nThen require it into your application with:\n\n```\nrequire 'hollerback'\n```\n\n##### If you're using Bundler...\n\nAdd the gem to your Gemfile:\n\n```\ngem 'hollerback'\n```\n\nAnd then `bundle install` to install the gem and its dependencies.\n\n### Usage\n\nEnable the callback pattern by including the `Hollerback` module into the class/module you want to trigger callbacks.\n\n```ruby\nclass NoteApi\n  include Hollerback\n\n  def get_note(name)\n    # ...\n  end\nend\n```\n\nThen add a `\u0026block` argument to the function you want to be callback enabled.\n\n```ruby\nclass NoteApi\n  include Hollerback\n\n  def get_note(name, \u0026block)\n    # ...\n  end\nend\n```\n\nAnd use `hollerback_for` to get a set of callbacks you can invoke:\n\n```ruby\nclass NoteApi\n  include Hollerback\n\n  def get_note(name, \u0026block)\n    hollerback_for(block) do |callbacks|\n      # ...\n    end\n  end\nend\n```\n\nThen trigger callbacks as you like, passing any arguments you need.\n\n```ruby\nclass NoteApi\n  include Hollerback\n\n  def get_note(name, \u0026block)\n    # Creates Callbacks object from the block\n    hollerback_for(block) do |callbacks|\n      begin\n        # Retrieves a HTTP response\n        response = make_note_request(name: name)\n\n        # Invoke Callbacks\n        when response.status\n        case 200\n          callbacks.respond_with(:found, response.body)\n        case 404\n          callbacks.respond_with(:not_found, name)\n        end\n      rescue =\u003e e\n        callbacks.respond_with(:error, e) \n      end\n    end\n  end\nend\n```\n\nAnd finally use your newly callback-enabled function with your callback DSL:\n\n```ruby\ndef write_note(name, content)\n  note = NoteApi.new.get_note(\"Grocery List\") do |on|\n    on.found do |note_json|\n      Note.from_json(note_json)\n    end\n    on.not_found do |name|\n      Note.create!(name: name)\n    end\n    on.error do |error|\n      raise \"Failed to retrieve note! Reason: #{error.message}\"\n    end\n  end\n\n  note.append(content)\nend\n```\n\n### Features\n\n##### #hollerback_for\n\nConverts an anonymous callback block into a `Hollerback::Callbacks` object that you can invoke callbacks from. Can be called as an instance or class method from any class that includes `Hollerback`.\n\n```ruby\nclass NoteApi\n  include Hollerback\n\n  def self.get_note(name, \u0026block)\n    hollerback_for(block) do |callbacks|\n      # ...\n    end\n  end\n\n  def get_note(name, \u0026block)\n    hollerback_for(block) do |callbacks|\n      # ...\n    end\n  end\nend\n```\n\nThis is the equivalent of:\n\n```ruby\ndef get_note(name, \u0026block)\n  callbacks = Hollerback::Callbacks.new(block)\nend\n```\n\nIf you override the behavior of `Hollerback::Callbacks` in a subclass, you can use it as your callbacks object instead:\n\n```ruby\nclass NoteCallbacks \u003c Hollerback::Callbacks\n  # ...\nend\n\nclass NoteApi\n  include Hollerback\n\n  def get_note(name, \u0026block)\n    hollerback_for(block, callback_class: NoteCallbacks) do |callbacks|\n      # ...\n    end\n  end\nend\n```\n\n##### #respond_with\n\nTriggers a callback, passing any arguments along. If the callback isn't defined, it raises a `NoMethodError`.\n\n```ruby\ncallbacks_block = Proc.new do |on|\n  on.no_args { \"No args.\" }\n  on.with_args { |a, b|  \"#{a}, #{b}\" }\n  on.with_arg_list { |*args| args }\n  on.with_arg_block { |\u0026block| block.call }\nend\n\ncallbacks = Hollerback::Callbacks.new(callbacks_block)\n\ncallbacks.respond_with(:no_args)\n# =\u003e \"No args.\"\ncallbacks.respond_with(:with_args, 1, 2)\n# =\u003e \"1, 2\"\ncallbacks.respond_with(:with_arg_list, *[1,2,3])\n# =\u003e [1,2,3]\ncallbacks.respond_with(:with_arg_block, \u0026(Proc.new { \"Block called.\" }))\n# =\u003e \"Block called.\"\ncallbacks.respond_with(:some_nonexisting_callback)\n# =\u003e NoMethodError: No callback 'some_nonexisting_callback' is defined.\n```\n\n##### #try_respond_with\n\nTriggers a callback like `respond_with`, passing any arguments along. If the callback isn't defined, it returns `nil`.\n\n```ruby\ncallbacks_block = Proc.new do |on|\n  on.no_args { \"No args.\" }\nend\n\ncallbacks = Hollerback::Callbacks.new(callbacks_block)\n\ncallbacks.try_respond_with(:no_args)\n# =\u003e \"No args.\"\ncallbacks.try_respond_with(:some_nonexisting_callback)\n# =\u003e nil\n```\n\n### Testing\n\nIf you're writing RSpec tests around code that uses callbacks, you can mock callbacks using the `rspec-hollerback-mocks` gem.\n\n```ruby\nit { expect(NoteApi).to receive(:get_note).with(name).and_callback(:found, note) }\n```\n\nCheck out the [`rspec-hollerback-mocks`](https://github.com/delner/rspec-hollerback-mocks) gem to learn more.\n\n## Development\n\nInstall dependencies using `bundle install`. Run tests using `bundle exec rspec`\n\n## Contributing\n\nBug reports and pull requests are welcome on GitHub at https://github.com/delner/hollerback.\n\n## License\n\nThe gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdelner%2Fhollerback","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdelner%2Fhollerback","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdelner%2Fhollerback/lists"}