{"id":21605345,"url":"https://github.com/alexander-senko/magic-support","last_synced_at":"2026-03-10T01:32:26.889Z","repository":{"id":264482912,"uuid":"893498987","full_name":"Alexander-Senko/magic-support","owner":"Alexander-Senko","description":"Utility classes and Ruby extensions beyond Active Support","archived":false,"fork":false,"pushed_at":"2024-12-07T09:18:12.000Z","size":25,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-05-06T19:12:40.098Z","etag":null,"topics":["core-ext","rspec","ruby","rubygems"],"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/Alexander-Senko.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":"CODE_OF_CONDUCT.md","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":"2024-11-24T15:52:55.000Z","updated_at":"2024-12-07T09:18:16.000Z","dependencies_parsed_at":"2024-11-24T17:18:06.087Z","dependency_job_id":"64466a54-5ca5-4a00-8568-4c25cd0d5ce0","html_url":"https://github.com/Alexander-Senko/magic-support","commit_stats":null,"previous_names":["alexander-senko/magic-support"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Alexander-Senko%2Fmagic-support","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Alexander-Senko%2Fmagic-support/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Alexander-Senko%2Fmagic-support/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Alexander-Senko%2Fmagic-support/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Alexander-Senko","download_url":"https://codeload.github.com/Alexander-Senko/magic-support/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252752060,"owners_count":21798723,"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":["core-ext","rspec","ruby","rubygems"],"created_at":"2024-11-24T20:12:56.872Z","updated_at":"2026-03-10T01:32:26.879Z","avatar_url":"https://github.com/Alexander-Senko.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ✨ Magic Support\n\n![GitHub Actions Workflow Status](\n\thttps://img.shields.io/github/actions/workflow/status/Alexander-Senko/magic-support/ci.yml\n)\n![Code Climate maintainability](\n\thttps://img.shields.io/codeclimate/maintainability-percentage/Alexander-Senko/magic-support\n)\n![Code Climate coverage](\n\thttps://img.shields.io/codeclimate/coverage/Alexander-Senko/magic-support\n)\n\nMagic Support is a collection of utility classes and standard library extensions\nthat were found useful for my pet projects.\n\nIt’s inspired by [Active Support](\n\thttps://github.com/rails/rails/tree/main/activesupport\n).\n\n## Installation\n\nInstall the gem and add to the application’s Gemfile by executing:\n\n```bash\nbundle add magic-support\n```\n\nIf Bundler is not being used to manage dependencies, install the gem by executing:\n\n```bash\ngem install magic-support\n```\n\n## Core extensions\n\n### Loading\n\nMagic Support is broken into small pieces so that only the desired extensions can be loaded.\nIt also has some convenience entry points to load related extensions in one shot, even all of them.\n\n#### Cherry-picking\n\nFor every single method defined as a core extension a note says where such a method is defined.\n\nThat means that you can `require` it like this:\n\n```ruby\nrequire 'magic/core_ext/\u003cmodule\u003e/\u003cextension\u003e'\n```\n\nMagic Support has been carefully revised so that cherry-picking a file loads only strictly needed dependencies, if any.\n\n#### Loading grouped core extensions\n\nAs a rule of thumb, extensions to `SomeClass` are available in\none shot by loading `magic/core_ext/some_class`.\n\nThus, to load all extensions to `Kernel`:\n\n```ruby\nrequire 'magic/core_ext/kernel'\n```\n\n#### Loading all core extensions\n\nYou may prefer just to load all core extensions, there is a file for that:\n\n```ruby\nrequire 'magic/core_ext'\n```\n\n### Extensions to all objects\n\n#### `#optional`\n\nYields self to the block and returns the result of the block if it’s truthy, and self otherwise.\n\n```ruby\nrand(6)                              # returns 0–5\n  .optional { it + 1 if one_based? } # returns 1–6 if 1-based, or\n                                     # the original 0–5 otherwise\n```\n\nIt can be considered as a conditional `#then`.\n\nGood usage for `#optional` is value piping in method chains with conditional processing:\n\n```ruby\n@people = Person\n  .optional { it.where created_at: (1.hour.ago...) if new? }\n  .optional { anonymize it if gdpr? }\n  .optional { try :decorate }\n```\n\nDefined in `core_ext/kernel/optional`.\n\n## Gems\n\n### Author\n\nIt holds authors info to be used primarily in gem specs.\n\n#### Loading\n\nPre-install Magic Support if you plan to use `Gem::Author` in your gemspec.\n\n```bash\ngem install magic-support\n```\n\n#### Usage\n\n1. Inherit `Gem::Author` inside your gem and add the authors’ info.\n\n\t```ruby\n\trequire 'rubygems/author'\n\t\n\tmodule MyLib\n\t  class Author \u003c Gem::Author\n\t    new(\n\t      name:   'Your Name',\n\t      email:  'Your.Name@email.service',\n\t      github: 'Your-GitHub-Username',\n\t    )\n\t  end\n\tend\n\t```\n\n2. You can call some helper methods now.\n\n\t```ruby\n\tGem::Specification.new do |spec|\n\t  spec.name     = 'my_lib'\n\t  spec.version  = MyLib::VERSION\n\t  spec.authors  = MyLib::Author.names\n\t  spec.email    = MyLib::Author.emails\n\t  spec.homepage = \"#{MyLib::Author.github_url}/#{spec.name}\"\n\tend\n\t```\n\n## RSpec\n\n### Method specs\n\nEnables one to write specs for single methods.\n\n\u003e [!WARNING]\n\u003e Planed for extraction into a separate gem.\n\n#### Loading\n\nRequire it in `spec_helper.rb`:\n\n```ruby\nrequire 'rspec/method'\n```\n\n#### Usage\n\nInclude a method reference into the description.\nThe reference should start with either\n- `.` for class methods or\n- `#` for instance ones.\n\n```ruby\nRSpec.describe MyClass do\n  describe '.class_method' do\n    its([arg1, arg2]) { is_expected.to be return_value }\n  end\n\n  describe '#instance_method' do\n    its([arg1, arg2]) { is_expected.to be return_value }\n  end\nend\n```\n\n\u003e [!NOTE]\n\u003e Though `rspec/its` is not needed, it could come useful (see [the article on method testing](\n\u003e \thttps://zverok.space/blog/2017-11-01-rspec-method-call.html\n\u003e )).\n\nWithin examples, `subject` is set to the corresponding `Method` instance.\nIn cases when the method couldn’t be found (e.g., due to delegation via `method_missing`), it’s set to a `Proc` instance\ninstead.\nAnyway, one may treat it as something _callable_.\n\nA receiver object is exposed via `receiver`.\nA method name is exposed as a `Symbol` via `method_name`.\n\n\u003e [!NOTE]\n\u003e `subject.name` may be undefined, use `method_name` instead.\n\n##### Delegated methods\n\nOne can use `it_behaves_like :delegated` for delegated methods.\nThis will ensure that calling the method calls the one of the same name on a delegate under the hood passing it the arguments.\n\n```ruby\nRSpec.describe MyClass do\n  describe '#method_with_arguments' do\n    it_behaves_like :delegated, to: delegate, with: [arg1, arg2]\n  end\n\n  describe '#method_without_arguments' do\n    it_behaves_like :delegated, to: delegate\n  end\nend\n```\n\n##### Module specs\n\nIt’s recommended to use class method notation, when writing specs for module functions.\n\n```ruby\nRSpec.describe MyModule do\n  describe '.module_function' do \n    # put the examples here\n  end\nend\n```\n\n##### Nesting\n\nOne may nest method specs.\nThis could be useful when a method being tested affects other methods.\nSee the spec for examples.\n\n## Development\n\nAfter checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.\n\nTo install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).\n\n## Contributing\n\nBug reports and pull requests are welcome on GitHub at https://github.com/Alexander-Senko/magic-support. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/Alexander-Senko/magic-support/blob/main/CODE_OF_CONDUCT.md).\n\n## License\n\nThe gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).\n\n## Code of Conduct\n\nEveryone interacting in the Magic::Support project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/Alexander-Senko/magic-support/blob/main/CODE_OF_CONDUCT.md).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexander-senko%2Fmagic-support","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falexander-senko%2Fmagic-support","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexander-senko%2Fmagic-support/lists"}