Issue #5582 has been reported by Simon Chiang. ---------------------------------------- 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.
on 2011-11-07 04:34
on 2011-11-24 03:34
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.
on 2012-03-27 16:53
Issue #5582 has been updated by mame (Yusuke Endoh). Status changed from Open to Assigned Assignee set to matz (Yukihiro Matsumoto) ---------------------------------------- Feature #5582: Allow clone of singleton methods on a BasicObject https://bugs.ruby-lang.org/issues/5582#change-25250 Author: thinkerbot (Simon Chiang) Status: Assigned Priority: Normal Assignee: matz (Yukihiro Matsumoto) 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.
on 2012-11-24 06:15
Issue #5582 has been updated by mame (Yusuke Endoh). Target version changed from 1.9.2 to next minor ---------------------------------------- Feature #5582: Allow clone of singleton methods on a BasicObject https://bugs.ruby-lang.org/issues/5582#change-33788 Author: thinkerbot (Simon Chiang) Status: Assigned Priority: Normal Assignee: matz (Yukihiro Matsumoto) Category: Target version: next minor 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.
on 2012-12-12 15:37
Issue #5582 has been updated by nobu (Nobuyoshi Nakada).
=begin
2.0 allows `method transplanting'.
module Clone
%i[clone initialize_copy initialize_dup initialize_clone].each do
|m|
define_method(m, Kernel.instance_method(m))
end
end
=end
----------------------------------------
Feature #5582: Allow clone of singleton methods on a BasicObject
https://bugs.ruby-lang.org/issues/5582#change-34663
Author: thinkerbot (Simon Chiang)
Status: Assigned
Priority: Normal
Assignee: matz (Yukihiro Matsumoto)
Category:
Target version: next minor
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.
Please log in before posting. Registration is free and takes only a minute.
Existing account
(Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
Log in with Google account | Log in with Yahoo account
No account? Register here.