From: George Koehler Date: 2011-11-24T11:34:23+09:00 Subject: [ruby-core:41274] [ruby-trunk - Feature #5582] Allow clone of singleton methods on a BasicObject Issue #5582 has been updated by George Koehler. =begin My first attempt: module Clone include Kernel (instance_methods - [:clone, :initialize_clone]).each {|m| undef_method m} end b = BasicObject.new class << b include ::Clone def single; "Quack!"; end end c = b.clone puts c.single Output: scratch.rb:3: warning: undefining `object_id' may cause serious problems Quack! Clone inherits from Kernel, but undefines all its instance methods except Clone#clone and Clone#initialize_clone. This technique has some awful side effects: Kernel === b and Kernel === c become true. Clone might inherit metamethods from Kernel (because I only undefined instance methods, not metamethods). =end ---------------------------------------- Feature #5582: Allow clone of singleton methods on a BasicObject http://redmine.ruby-lang.org/issues/5582 Author: Simon Chiang Status: Open Priority: Normal Assignee: Category: Target version: 1.9.2 Currently I do not know of a way to implement something like 'clone' on a BasicObject subclass. This is as close as I've gotten but as you can see the singleton methods are not propagated to the clone. require 'test/unit' class Context < BasicObject def _singleton_class_ class << self SINGLETON_CLASS = self def _singleton_class_ SINGLETON_CLASS end end _singleton_class_ end def _class_ _singleton_class_.superclass end def _extend_(mod) mod.__send__(:extend_object, self) end def _initialize_clone_(orig) # set variables as needed end def _clone_ clone = _class_.allocate clone._initialize_clone_(self) _singleton_class_.included_modules.each {|mod| clone._extend_ mod } clone end end class ContextTest < Test::Unit::TestCase module A def a :a end end def test__clone__inherits_modules context = Context.new context._extend_ A clone = context._clone_ assert_equal :a, clone.a end def test__clone__inherits_singleton_methods context = Context.new def context.a :a end clone = context._clone_ assert_equal :a, clone.a # fails end end Is there a way to do this that I don't see? If not, then I request that a way be added - perhaps by allowing the singleton_class to be set somehow. In my case I am using Context as the context for a dsl where methods write to a target (an instance variable). I want to be able to clone a context such that I can have multiple contexts with the same methods, including extensions and singletons, that write to different targets. Thank you. -- http://redmine.ruby-lang.org