{"id":15561061,"url":"https://github.com/jirutka/corefines","last_synced_at":"2025-04-19T11:56:44.178Z","repository":{"id":26593948,"uuid":"30048710","full_name":"jirutka/corefines","owner":"jirutka","description":":gem: A collection of refinements for Ruby core classes with a compatibility mode for older Rubies and a convenient syntactic sugar.","archived":false,"fork":false,"pushed_at":"2021-07-21T17:08:53.000Z","size":142,"stargazers_count":27,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-29T07:33:49.470Z","etag":null,"topics":["extensions","refinements","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/jirutka.png","metadata":{"files":{"readme":"README.adoc","changelog":"CHANGELOG.adoc","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-01-30T00:38:41.000Z","updated_at":"2023-11-10T08:24:36.000Z","dependencies_parsed_at":"2022-09-05T15:31:45.563Z","dependency_job_id":null,"html_url":"https://github.com/jirutka/corefines","commit_stats":null,"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jirutka%2Fcorefines","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jirutka%2Fcorefines/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jirutka%2Fcorefines/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jirutka%2Fcorefines/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jirutka","download_url":"https://codeload.github.com/jirutka/corefines/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248868419,"owners_count":21174751,"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":["extensions","refinements","ruby"],"created_at":"2024-10-02T16:05:11.422Z","updated_at":"2025-04-19T11:56:44.153Z","avatar_url":"https://github.com/jirutka.png","language":"Ruby","readme":"= Corefines\nJakub Jirutka \u003chttps://github.com/jirutka[@jirutka]\u003e\n:source-language: ruby\n// custom\n:gem-name: corefines\n:gem-version: 1.11.1\n:gh-name: jirutka/{gem-name}\n:gh-branch: master\n:badge-style: flat\n:doc-base-url: http://www.rubydoc.info/github/{gh-name}/{gh-branch}/Corefines\n\nifdef::env-github[]\nimage:https://img.shields.io/travis/{gh-name}/{gh-branch}.svg?style={badge-style}[Build Status, link=\"https://travis-ci.org/{gh-name}\"]\nimage:https://img.shields.io/codeclimate/coverage/github/{gh-name}.svg?style={badge-style}[Test Coverage, link=\"https://codeclimate.com/github/{gh-name}\"]\nimage:https://img.shields.io/codeclimate/github/{gh-name}.svg?style={badge-style}[Code Climate, link=\"https://codeclimate.com/github/{gh-name}\"]\nimage:https://img.shields.io/gem/v/{gem-name}.svg?style={badge-style}[Gem Version, link=\"https://rubygems.org/gems/{gem-name}\"]\nimage:https://img.shields.io/badge/yard-docs-blue.svg?style={badge-style}[Yard Docs, link=\"http://www.rubydoc.info/github/{gh-name}/{gh-branch}\"]\nendif::env-github[]\n\nCorefines is a collection of general purpose _refinements_ for extending the core capabilities of Ruby’s built-in classes.\nIt also provides a \u003c\u003ccompatibility-mode\u003e\u003e for older Ruby versions and alternative Ruby implementations that don’t support refinements (yet).\n\n\n== Why refinements?\n\nExtending core classes with so called monkey-paching pollutes the _global_ scope, so it affects all files on the `$LOAD_PATH`, i.e. whole application including used gems.\nIt’s not usually so big deal when you’re doing it in your application, but it’s very dangerous when used in a gem (library).\nThis can result in strange and hard to debug behaviour if another gem overrides a core class with the same method as your gem, but different implementation, and both gems are used together.\n\nRefinements basically allows you to put monkey patches in an isolated namespace, so that your changes to core classes don’t affect other code.\n\nTODO\n\n\n== Installation\n\nAdd this line to your application’s Gemfile:\n\n[source, subs=\"+attributes\"]\ngem '{gem-name}', '~\u003e {gem-version}'\n\nor to your gemspec:\n\n[source, subs=\"+attributes\"]\ns.add_runtime_dependency '{gem-name}', '~\u003e {gem-version}'\n\nand then execute:\n\n[source, sh]\n$ bundle install\n\n\n== Using\n\nFirst, you must require `corefines` prior using:\n\n[source]\nrequire 'corefines'\n\nThis will _not_ activate any extensions (just register them), even when running in compatibility mode.\nExtensions (refinements) are activated selectively with the method http://ruby-doc.org/core-2.2.0/Module.html#method-i-using[`using`].\n\nRefinements are organized into modules by class which they refine, and further into submodules for individual methods.\nWhen an extension refines multiple classes, then it’s included in a module named after their nearest common ancestor (superclass).\n\n[source, plain]\nCorefines::\u003cCLASS\u003e::\u003cMETHOD\u003e\n\nA single extension can be imported into the current scope classically, e.g.:\n\n[source]\nusing Corefines::Object::ThenIf\n\nor preferably using its “alias”:\n\n[source]\nusing Corefines::Object::then_if\n\nIf you want to include all extensions for the class, then you can just import the parent module, e.g.:\n\n[source]\nusing Corefines::Object\n\nBut more often you want to include multiple extensions for the class, but not all of them, e.g.:\n\n[source]\nusing Corefines::Object::then_if\nusing Corefines::Object::in?\n\nthis can be abbreviated to:\n\n[source]\nusing Corefines::Object[:then_if, :in?]\n\nIf you feel that _Corefines_ is too long, then you can also use abbreviation _CF_ instead:\n\n[source]\nusing CF::Object::then_if\n\nRefinements can be activated (with `using`) at top-level (per file), inside a class, module or a method.\n\n\n== Compatibility mode\n\nRefinements are still a young feature, so there’s a possibility that your gem or application will have to work on a Ruby platform that doesn’t fully support refinements yet.\n\nThe main Ruby implementation, https://en.wikipedia.org/wiki/Ruby_MRI[MRI] (aka CRuby), supports refinements since version 2.1.0 (https://www.ruby-lang.org/en/news/2013/12/25/ruby-2-1-0-is-released/[released in 25 Dec 2013]).\nfootnote:[Actually, refinements has been introduced to MRI in 2.0.0, as an experimental feature. However, its design and implementation has been changed then, so refinements in 2.0.x and 2.1+ behaves quite differently.]\nVersion 2.0.0 (https://www.ruby-lang.org/en/news/2013/02/24/ruby-2-0-0-p0-is-released/[released in 24 Feb 2013]) is still supported though.\nhttp://www.jruby.org/[JRuby] doesn’t support refinements yet, it’s planned in the upcoming version 9.0.0.0 (https://github.com/jruby/jruby/issues/1062[#1062]).\nhttp://rubini.us/[Rubinius] also doesn’t support refinements yet.\n\nThis gem is a collection of pure refinements, and yet, it works even on older Rubies that don’t support refinements.\nWait… how?\nWell, when you use the gem with an older Ruby, it’s actually cheating.\nInstead of locally scoped changes, it falls back to global monkey-patching.\n\nThe Corefines gem adds `refine` and `using` methods to the core classes, so you can define and use refinements just like in newer Rubies.\nBut internally it works very differently.\nThe `refine` method adds a given block to a collection of pending “refinements” inside its module.\nWhen `using` is called _first time_ for the module, it _evaluates_ module’s “refinements” in context of the target classes (i.e. do a monkey-patch).\n\nNot ideal indeed, but probably the best of what we can achieve.\n\n\n== List of refinements\n\n* {doc-base-url}/Array[Array]\n** {doc-base-url}/Array/Second[#second]\n** {doc-base-url}/Array/Third[#third]\n** {doc-base-url}/Array/Wrap[.wrap]\n* {doc-base-url}/Class[Class]\n** {doc-base-url}/Class/Descendants[#descendants]\n* {doc-base-url}/Enumerable[Enumerable]\n** {doc-base-url}/Enumerable/IndexBy[#index_by]\n** {doc-base-url}/Enumerable/Many[#many?]\n** {doc-base-url}/Enumerable/MapBy[#map_by]\n** {doc-base-url}/Enumerable/MapSend[#map_send]\n** {doc-base-url}/Enumerable/MapTo[#map_to]\n* {doc-base-url}/Hash[Hash]\n** {doc-base-url}/Hash/OpAdd[#+]\n** {doc-base-url}/Hash/Compact[#compact]\n** {doc-base-url}/Hash/Compact[#compact!]\n** {doc-base-url}/Hash/Except[#except]\n** {doc-base-url}/Hash/Except[#except!]\n** {doc-base-url}/Hash/FlatMap[#flat_map]\n** {doc-base-url}/Hash/Only[#only]\n** {doc-base-url}/Hash/Only[#only!]\n** {doc-base-url}/Hash/Recurse[#recurse]\n** {doc-base-url}/Hash/Rekey[#rekey]\n** {doc-base-url}/Hash/Rekey[#rekey!]\n** {doc-base-url}/Hash/SymbolizeKeys[#symbolize_keys]\n** {doc-base-url}/Hash/SymbolizeKeys[#symbolize_keys!]\n* {doc-base-url}/Module[Module]\n** {doc-base-url}/Module/AliasClassMethod[#alias_class_method]\n** {doc-base-url}/Module/AliasMethodChain[#alias_method_chain]\n* {doc-base-url}/Object[Object]\n** {doc-base-url}/Object/Blank[#blank?]\n** {doc-base-url}/Object/DeepDup[#deep_dup]\n** {doc-base-url}/Object/Else[#else]\n** {doc-base-url}/Object/In[#in?]\n** {doc-base-url}/Object/InstanceValues[#instance_values]\n** {doc-base-url}/Object/Blank[#presence]\n** {doc-base-url}/Object/Then[#then]\n** {doc-base-url}/Object/ThenIf[#then_if]\n** {doc-base-url}/Object/Try[#try]\n** {doc-base-url}/Object/Try[#try!]\n* {doc-base-url}/String[String]\n** {doc-base-url}/String/Camelcase[#camelcase]\n** {doc-base-url}/String/Color[#color]\n** {doc-base-url}/String/Concat[#concat!]\n** {doc-base-url}/String/Decolor[#decolor]\n** {doc-base-url}/String/ForceUTF8[#force_utf8]\n** {doc-base-url}/String/ForceUTF8[#force_utf8!]\n** {doc-base-url}/String/Indent[#indent]\n** {doc-base-url}/String/RelativePathFrom[#relative_path_from]\n** {doc-base-url}/String/Remove[#remove]\n** {doc-base-url}/String/SnakeCase[#snake_case]\n** {doc-base-url}/String/ToB[#to_b]\n** {doc-base-url}/String/ToRe[#to_re]\n** {doc-base-url}/String/Unindent[#unindent] (alias `#strip_heredoc`)\n* {doc-base-url}/Symbol[Symbol]\n** {doc-base-url}/Symbol/Call[#call]\n\n\n== Acknowledgement\n\nMost of the extension methods are based on, or highly inspired from:\n\n* https://github.com/rails/rails/tree/master/activesupport[Active Support (Ruby extensions)]\n* https://github.com/rubyworks/facets[Ruby Facets]\n* https://github.com/gregwebs/methodchain[methodchain]\n* https://github.com/fazibear/colorize[colorize]\n* https://github.com/seamusabshere/to_regexp[to_regexp]\n\nVery useful articles about refinements and how to “trick” them:\n\n* https://www.new-bamboo.co.uk/blog/2014/02/05/refinements-under-the-knife/[\nRefinements under the knife] by https://github.com/leemachin[@leemachin]\n* http://qiita.com/joker1007/items/68d066a12bc763bd2cb4[Refinement関係の小技とできない事をまとめてみた] by https://github.com/joker1007[@joker1007]\n\n\n== Contributing\n\n. Fork it.\n. Create your feature branch (`git checkout -b my-new-feature`).\n. Commit your changes (`git commit -am 'Add some feature'`).\n. Push to the branch (`git push origin my-new-feature`).\n. Create a new Pull Request.\n\n\n== License\n\nThis project is licensed under http://opensource.org/licenses/MIT/[MIT License].\nFor the full text of the license, see the link:LICENSE[LICENSE] file.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjirutka%2Fcorefines","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjirutka%2Fcorefines","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjirutka%2Fcorefines/lists"}