{"id":17942637,"url":"https://github.com/petercamilleri/full_clone","last_synced_at":"2025-08-02T12:34:50.496Z","repository":{"id":22783853,"uuid":"26129961","full_name":"PeterCamilleri/full_clone","owner":"PeterCamilleri","description":"A recursive, deep copy version of clone with exclusion control and tolerance of non-clonable values.","archived":false,"fork":false,"pushed_at":"2021-05-19T19:26:05.000Z","size":32,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-09T08:51:54.850Z","etag":null,"topics":["deep","gem","ruby","ruby-gem","safe","utility"],"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/PeterCamilleri.png","metadata":{"files":{"readme":"README.md","changelog":null,"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}},"created_at":"2014-11-03T17:25:10.000Z","updated_at":"2023-03-05T04:20:47.000Z","dependencies_parsed_at":"2022-07-19T01:02:22.078Z","dependency_job_id":null,"html_url":"https://github.com/PeterCamilleri/full_clone","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PeterCamilleri%2Ffull_clone","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PeterCamilleri%2Ffull_clone/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PeterCamilleri%2Ffull_clone/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PeterCamilleri%2Ffull_clone/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/PeterCamilleri","download_url":"https://codeload.github.com/PeterCamilleri/full_clone/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247008822,"owners_count":20868428,"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":["deep","gem","ruby","ruby-gem","safe","utility"],"created_at":"2024-10-29T03:06:33.755Z","updated_at":"2025-04-03T13:27:41.807Z","avatar_url":"https://github.com/PeterCamilleri.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# FullClone\n\nThe standard clone method creates a fresh instance of most (non-scalar) objects\nbut does not clone internal state. This internal state remains aliased in the\ncloned copy. The full_clone method digs deep and makes copies of these internal\nvariables, not just arrays and hashes. It also allows classes to specify an\nexclusion list of variables that are not to be processed.\n\nNew for version 0.0.10, now 84% faster (at least full_dup was in my tests).\n\nThis comprehensive approach creates another issue to be resolved. In Ruby, if an\nattempt is made to clone an immutable data item like a number, an error occurs.\nThe justification for this uncharacteristic strictness is not at all clear, but\nit does mean that the clone operation must be applied with great care.\n\nUnlike the standard clone method, the full\\_clone method does not throw an\nexception when it sees un-clonable value objects like 42 or true. These values\nsimply return themselves. This is deemed correct because those types of objects\nare immutable and do not need to be duped. Instead of raising an exception, the\ncode returns the immutable object instead.\n\nAnother issue that this gem deals with is that of data with looping reference\nchains. To handle this, the code tracks object ID values and does not re-clone\ndata that has already been cloned. Thus even nasty edge cases are handled\nwithout any special effort on the part of the application programmer.\n\n## Family Overview\n\nThis gem is a member of a family of four gems that all provide data copying\nservices in a safe, easy to use format. The following outlines the available\ngems and how to chose from among them.\n\nDepth / Action | Need to copy all. | Need to copy data only.\n---------------|------------------------------|------------\nNeed a shallow copy | require 'safe\\_clone' | require 'safe\\_dup'\nNeed a full copy    | require 'full\\_clone' | require 'full\\_dup'\n\n\u003cbr\u003e**Notes**\n* Since none of these gems override the default clone and dup\nmethods, the default behaviors remain available. Further, if multiple,\ndiffering requirements exists, more than one family member gem may be\nemployed in the same project without fear of conflict.\n* If multiple family gems are employed, they will each need to be installed and\nrequired into the application. See below for details.\n* Meta-data attributes include the frozen status and singleton methods. However\nthe tainted status is always copied.\n\n\n\n## Installation\n\nAdd this line to your application's Gemfile:\n\n    gem 'full_clone'\n\nAnd then execute:\n\n    $ bundle\n\nOr install it yourself as:\n\n    $ gem install full_clone\n\nThe safe_dup gem is at: ( https://rubygems.org/gems/safe_dup )\n\u003cbr\u003eThe safe_clone gem is at: ( https://rubygems.org/gems/safe_clone )\n\u003cbr\u003eThe full_dup gem is at: ( https://rubygems.org/gems/full_dup )\n\u003cbr\u003eThe full_clone gem is at: ( https://rubygems.org/gems/full_clone )\n\n## Usage\n\n    require 'full_clone'\n\nthen, in those places where regular clone was problematic, use:\n\n    foo = my_object.full_clone\n\ninstead of\n\n    foo = my_object.clone\n\nTo exclude some instance variables from the deep cloning process, define a\nfull_clone_exclude method in the required class:\n\n```ruby\ndef full_clone_exclude\n  [:@bad_var1, :@bad_var2, :@bad_var_etc]\nend\n```\nThis also can be applied to arrays and hashes. In this case, it is possible to\ndefine a singleton method on the cloned data. Then the exclude method would\nreturn an array of array indexes or hash keys to be omitted from the full clone\nrecursion. Here is an example that never clones the first two elements of the\narray:\n\n```ruby\nmy_array.define_singleton_method(:full_clone_exclude) { [0, 1] }\n```\n\n## Notes\n\nThe full_clone gem tracks its progress and handles data objects that\ncontain loops, cycles, and other forms of recursion. In order to do this,\nit relies heavily on the object_id property of the data being copied.\nIf object_id is broken, then full_clone and hashes and ... will also be\nbroken!\n\n\n## Contributing\n\n#### Plan A\n\n1. Fork it ( https://github.com/PeterCamilleri/full_clone/fork )\n2. Create your feature branch (`git checkout -b my-new-feature`)\n3. Commit your changes (`git commit -am 'Add some feature'`)\n4. Push to the branch (`git push origin my-new-feature`)\n5. Create new Pull Request\n\n#### Plan B\n\nGo to the GitHub repository and raise an issue calling attention to some\naspect that could use some TLC or a suggestion or an idea.\n\n## License\n\nThe gem is available as open source under the terms of the\n[MIT License](./LICENSE.txt).\n\n## Code of Conduct\n\nEveryone interacting in the fully_freeze project’s codebases, issue trackers,\nchat rooms and mailing lists is expected to follow the\n[code of conduct](./CODE_OF_CONDUCT.md).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpetercamilleri%2Ffull_clone","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpetercamilleri%2Ffull_clone","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpetercamilleri%2Ffull_clone/lists"}