Forum: Ruby-core [ruby-trunk - Feature #6308][Open] Eliminate delegation from WeakRef

Posted by Charles Nutter (headius)
on 2012-04-17 10:02
(Received via mailing list)
Issue #6308 has been reported by headius (Charles Nutter).

----------------------------------------
Feature #6308: Eliminate delegation from WeakRef
https://bugs.ruby-lang.org/issues/6308

Author: headius (Charles Nutter)
Status: Open
Priority: Normal
Assignee:
Category:
Target version:


WeakRef's delegation features are a really awful pattern that should not 
be allowed in future versions of Ruby.

WeakRef makes no guarantees as to the liveness of its contained object. 
It can be collected at any time if there are no strong references to it.

WeakRef currently uses delegation to pass method calls through to the 
contained object. This encourages a pattern where a WeakRef is passed to 
methods that expect to have a reference to the underlying object, making 
it appear to be that object.

Unfortunately, this is *never* a good idea. Because the object can be 
collected at any time, you may get a nil reference from __getobj__ 
*arbitrarily* in code that tries to call methods against the given 
WeakRef. That means using WeakRef as a delegate will always result in 
unreliable code, and errors may happen for inexplicable reasons.

I believe Ruby 2.0 should eliminate WeakRef's delegation features and 
make it a simple reference holder. There's no safe way to use a weak 
reference except to grab a reference to the object, check that it is 
alive (non-nil) and then proceed with the use of the object, as follows:

obj = weakref.__getobj__
raise AppropriateError unless obj
obj.do_something
obj.do_something_else

Along with eliminating delegation, I would recommend simply making the 
get method #get, since the uglier #__getobj__ is only named that way 
because it is not delegated.
Posted by Nobuyoshi Nakada (nobu)
on 2012-04-17 13:01
(Received via mailing list)
Issue #6308 has been updated by nobu (Nobuyoshi Nakada).

Category set to lib

It should be another new class, I think.
----------------------------------------
Feature #6308: Eliminate delegation from WeakRef
https://bugs.ruby-lang.org/issues/6308#change-25952

Author: headius (Charles Nutter)
Status: Open
Priority: Normal
Assignee:
Category: lib
Target version:


WeakRef's delegation features are a really awful pattern that should not 
be allowed in future versions of Ruby.

WeakRef makes no guarantees as to the liveness of its contained object. 
It can be collected at any time if there are no strong references to it.

WeakRef currently uses delegation to pass method calls through to the 
contained object. This encourages a pattern where a WeakRef is passed to 
methods that expect to have a reference to the underlying object, making 
it appear to be that object.

Unfortunately, this is *never* a good idea. Because the object can be 
collected at any time, you may get a nil reference from __getobj__ 
*arbitrarily* in code that tries to call methods against the given 
WeakRef. That means using WeakRef as a delegate will always result in 
unreliable code, and errors may happen for inexplicable reasons.

I believe Ruby 2.0 should eliminate WeakRef's delegation features and 
make it a simple reference holder. There's no safe way to use a weak 
reference except to grab a reference to the object, check that it is 
alive (non-nil) and then proceed with the use of the object, as follows:

obj = weakref.__getobj__
raise AppropriateError unless obj
obj.do_something
obj.do_something_else

Along with eliminating delegation, I would recommend simply making the 
get method #get, since the uglier #__getobj__ is only named that way 
because it is not delegated.
Posted by Charles Nutter (headius)
on 2012-04-17 18:44
(Received via mailing list)
Issue #6308 has been updated by headius (Charles Nutter).


Perhaps under the GC module. Seems better than under ObjectSpace

I also think WeakMap should perhaps be moved under GC.

GC::WeakRef
GC::WeakMap
GC::ReferenceQueue

The top-level WeakRef library should probably be deprecated, then, and 
implemented in terms of GC::WeakRef.
----------------------------------------
Feature #6308: Eliminate delegation from WeakRef
https://bugs.ruby-lang.org/issues/6308#change-25977

Author: headius (Charles Nutter)
Status: Open
Priority: Normal
Assignee:
Category: lib
Target version:


WeakRef's delegation features are a really awful pattern that should not 
be allowed in future versions of Ruby.

WeakRef makes no guarantees as to the liveness of its contained object. 
It can be collected at any time if there are no strong references to it.

WeakRef currently uses delegation to pass method calls through to the 
contained object. This encourages a pattern where a WeakRef is passed to 
methods that expect to have a reference to the underlying object, making 
it appear to be that object.

Unfortunately, this is *never* a good idea. Because the object can be 
collected at any time, you may get a nil reference from __getobj__ 
*arbitrarily* in code that tries to call methods against the given 
WeakRef. That means using WeakRef as a delegate will always result in 
unreliable code, and errors may happen for inexplicable reasons.

I believe Ruby 2.0 should eliminate WeakRef's delegation features and 
make it a simple reference holder. There's no safe way to use a weak 
reference except to grab a reference to the object, check that it is 
alive (non-nil) and then proceed with the use of the object, as follows:

obj = weakref.__getobj__
raise AppropriateError unless obj
obj.do_something
obj.do_something_else

Along with eliminating delegation, I would recommend simply making the 
get method #get, since the uglier #__getobj__ is only named that way 
because it is not delegated.
Posted by mame (Yusuke Endoh) (Guest)
on 2012-04-19 21:54
(Received via mailing list)
Issue #6308 has been updated by mame (Yusuke Endoh).

Status changed from Open to Feedback

Hello,

2012/4/17, headius (Charles Nutter) <headius@headius.com>:
> WeakRef's delegation features are a really awful pattern that should not be
> allowed in future versions of Ruby.


Maybe I understood your subject, but your proposal is not clear.
Could you please make it concrete?


"change the behavior of lib/weakref.rb in 2.0"

=> Impossible, because of matz's 2.0 compatibility policy.


"change the behavior of lib/weakref.rb in 3.0"

=> Maybe possible if matz accepts.  Please create a patch that warn
   a user when the delegation features are used.
   Then, I'll set this ticket as 3.0 issue.


"deprecate lib/weakref.rb and add an alternative library"

=> Please show us the alternative first.

--
Yusuke Endoh <mame@tsg.ne.jp>
----------------------------------------
Feature #6308: Eliminate delegation from WeakRef
https://bugs.ruby-lang.org/issues/6308#change-26026

Author: headius (Charles Nutter)
Status: Feedback
Priority: Normal
Assignee:
Category: lib
Target version:


WeakRef's delegation features are a really awful pattern that should not 
be allowed in future versions of Ruby.

WeakRef makes no guarantees as to the liveness of its contained object. 
It can be collected at any time if there are no strong references to it.

WeakRef currently uses delegation to pass method calls through to the 
contained object. This encourages a pattern where a WeakRef is passed to 
methods that expect to have a reference to the underlying object, making 
it appear to be that object.

Unfortunately, this is *never* a good idea. Because the object can be 
collected at any time, you may get a nil reference from __getobj__ 
*arbitrarily* in code that tries to call methods against the given 
WeakRef. That means using WeakRef as a delegate will always result in 
unreliable code, and errors may happen for inexplicable reasons.

I believe Ruby 2.0 should eliminate WeakRef's delegation features and 
make it a simple reference holder. There's no safe way to use a weak 
reference except to grab a reference to the object, check that it is 
alive (non-nil) and then proceed with the use of the object, as follows:

obj = weakref.__getobj__
raise AppropriateError unless obj
obj.do_something
obj.do_something_else

Along with eliminating delegation, I would recommend simply making the 
get method #get, since the uglier #__getobj__ is only named that way 
because it is not delegated.
Posted by Charles Nutter (headius)
on 2012-04-28 08:01
(Received via mailing list)
Issue #6308 has been updated by headius (Charles Nutter).


My proposal is that at some time deemed acceptable by ruby-core and 
Matz, the delegate-based WeakRef should go away, and that in Ruby 2.0 a 
"preferred" non-delegate WeakRef be added (ideally along with the 
reference queue support in my other bug).

Here is a patch that adds a non-delegate WeakRef implementation: 
https://gist.github.com/2516417

This is modeled after the Java WeakRef class, which can only be 
traversed or cleared. Again, I hope that this would be implemented in an 
efficient way as part of the GC subsystem, but this implementation 
should show what I'm looking for. I still whole-heartedly believe that 
using WeakRef as a delegate is an awful, awful pattern that should be 
discouraged now and unavailable in the future. This patch would force 
users to retrieve the weak reference into a hard reference, check it for 
liveness, and *then* proceed to use the object, which is the only safe 
way to deal with weak references.
----------------------------------------
Feature #6308: Eliminate delegation from WeakRef
https://bugs.ruby-lang.org/issues/6308#change-26281

Author: headius (Charles Nutter)
Status: Feedback
Priority: Normal
Assignee:
Category: lib
Target version:


WeakRef's delegation features are a really awful pattern that should not 
be allowed in future versions of Ruby.

WeakRef makes no guarantees as to the liveness of its contained object. 
It can be collected at any time if there are no strong references to it.

WeakRef currently uses delegation to pass method calls through to the 
contained object. This encourages a pattern where a WeakRef is passed to 
methods that expect to have a reference to the underlying object, making 
it appear to be that object.

Unfortunately, this is *never* a good idea. Because the object can be 
collected at any time, you may get a nil reference from __getobj__ 
*arbitrarily* in code that tries to call methods against the given 
WeakRef. That means using WeakRef as a delegate will always result in 
unreliable code, and errors may happen for inexplicable reasons.

I believe Ruby 2.0 should eliminate WeakRef's delegation features and 
make it a simple reference holder. There's no safe way to use a weak 
reference except to grab a reference to the object, check that it is 
alive (non-nil) and then proceed with the use of the object, as follows:

obj = weakref.__getobj__
raise AppropriateError unless obj
obj.do_something
obj.do_something_else

Along with eliminating delegation, I would recommend simply making the 
get method #get, since the uglier #__getobj__ is only named that way 
because it is not delegated.
Posted by mame (Yusuke Endoh) (Guest)
on 2012-05-03 04:52
(Received via mailing list)
Issue #6308 has been updated by mame (Yusuke Endoh).

Status changed from Feedback to Assigned
Assignee set to matz (Yukihiro Matsumoto)

Thanks, please wait a "ruling" of matz.

--
Yusuke Endoh <mame@tsg.ne.jp>
----------------------------------------
Feature #6308: Eliminate delegation from WeakRef
https://bugs.ruby-lang.org/issues/6308#change-26403

Author: headius (Charles Nutter)
Status: Assigned
Priority: Normal
Assignee: matz (Yukihiro Matsumoto)
Category: lib
Target version:


WeakRef's delegation features are a really awful pattern that should not 
be allowed in future versions of Ruby.

WeakRef makes no guarantees as to the liveness of its contained object. 
It can be collected at any time if there are no strong references to it.

WeakRef currently uses delegation to pass method calls through to the 
contained object. This encourages a pattern where a WeakRef is passed to 
methods that expect to have a reference to the underlying object, making 
it appear to be that object.

Unfortunately, this is *never* a good idea. Because the object can be 
collected at any time, you may get a nil reference from __getobj__ 
*arbitrarily* in code that tries to call methods against the given 
WeakRef. That means using WeakRef as a delegate will always result in 
unreliable code, and errors may happen for inexplicable reasons.

I believe Ruby 2.0 should eliminate WeakRef's delegation features and 
make it a simple reference holder. There's no safe way to use a weak 
reference except to grab a reference to the object, check that it is 
alive (non-nil) and then proceed with the use of the object, as follows:

obj = weakref.__getobj__
raise AppropriateError unless obj
obj.do_something
obj.do_something_else

Along with eliminating delegation, I would recommend simply making the 
get method #get, since the uglier #__getobj__ is only named that way 
because it is not delegated.
Posted by Charles Nutter (headius)
on 2012-11-16 17:00
(Received via mailing list)
Issue #6308 has been updated by headius (Charles Nutter).


Seven months and no activity. I still would like to see delegate-based 
Weakref go away, but I know the official plan is to have no backward 
compatibility. Unfortunately, delegate-based Weakref is still a bad, 
broken implementation, and I think it should go away. 2.0 is as good a 
time as any.
----------------------------------------
Feature #6308: Eliminate delegation from WeakRef
https://bugs.ruby-lang.org/issues/6308#change-32971

Author: headius (Charles Nutter)
Status: Assigned
Priority: Normal
Assignee: matz (Yukihiro Matsumoto)
Category: lib
Target version:


WeakRef's delegation features are a really awful pattern that should not 
be allowed in future versions of Ruby.

WeakRef makes no guarantees as to the liveness of its contained object. 
It can be collected at any time if there are no strong references to it.

WeakRef currently uses delegation to pass method calls through to the 
contained object. This encourages a pattern where a WeakRef is passed to 
methods that expect to have a reference to the underlying object, making 
it appear to be that object.

Unfortunately, this is *never* a good idea. Because the object can be 
collected at any time, you may get a nil reference from __getobj__ 
*arbitrarily* in code that tries to call methods against the given 
WeakRef. That means using WeakRef as a delegate will always result in 
unreliable code, and errors may happen for inexplicable reasons.

I believe Ruby 2.0 should eliminate WeakRef's delegation features and 
make it a simple reference holder. There's no safe way to use a weak 
reference except to grab a reference to the object, check that it is 
alive (non-nil) and then proceed with the use of the object, as follows:

obj = weakref.__getobj__
raise AppropriateError unless obj
obj.do_something
obj.do_something_else

Along with eliminating delegation, I would recommend simply making the 
get method #get, since the uglier #__getobj__ is only named that way 
because it is not delegated.
Posted by mame (Yusuke Endoh) (Guest)
on 2012-11-24 02:55
(Received via mailing list)
Issue #6308 has been updated by mame (Yusuke Endoh).

Target version set to next minor


----------------------------------------
Feature #6308: Eliminate delegation from WeakRef
https://bugs.ruby-lang.org/issues/6308#change-33722

Author: headius (Charles Nutter)
Status: Assigned
Priority: Normal
Assignee: matz (Yukihiro Matsumoto)
Category: lib
Target version: next minor


WeakRef's delegation features are a really awful pattern that should not 
be allowed in future versions of Ruby.

WeakRef makes no guarantees as to the liveness of its contained object. 
It can be collected at any time if there are no strong references to it.

WeakRef currently uses delegation to pass method calls through to the 
contained object. This encourages a pattern where a WeakRef is passed to 
methods that expect to have a reference to the underlying object, making 
it appear to be that object.

Unfortunately, this is *never* a good idea. Because the object can be 
collected at any time, you may get a nil reference from __getobj__ 
*arbitrarily* in code that tries to call methods against the given 
WeakRef. That means using WeakRef as a delegate will always result in 
unreliable code, and errors may happen for inexplicable reasons.

I believe Ruby 2.0 should eliminate WeakRef's delegation features and 
make it a simple reference holder. There's no safe way to use a weak 
reference except to grab a reference to the object, check that it is 
alive (non-nil) and then proceed with the use of the object, as follows:

obj = weakref.__getobj__
raise AppropriateError unless obj
obj.do_something
obj.do_something_else

Along with eliminating delegation, I would recommend simply making the 
get method #get, since the uglier #__getobj__ is only named that way 
because it is not delegated.
Posted by Charles Nutter (headius)
on 2013-03-15 18:30
(Received via mailing list)
Issue #6308 has been updated by headius (Charles Nutter).


I request a ruling by matz for making the backward-incompatible change 
of having Weakref no longer be a Delegate. Alternatively, make it a 
Delegate where all delegated methods warn that you shouldn't use it as a 
Delegate.

If necessary I will move this feature request to CommonRuby.
----------------------------------------
Feature #6308: Eliminate delegation from WeakRef
https://bugs.ruby-lang.org/issues/6308#change-37634

Author: headius (Charles Nutter)
Status: Assigned
Priority: Normal
Assignee: matz (Yukihiro Matsumoto)
Category: lib
Target version: next minor


WeakRef's delegation features are a really awful pattern that should not 
be allowed in future versions of Ruby.

WeakRef makes no guarantees as to the liveness of its contained object. 
It can be collected at any time if there are no strong references to it.

WeakRef currently uses delegation to pass method calls through to the 
contained object. This encourages a pattern where a WeakRef is passed to 
methods that expect to have a reference to the underlying object, making 
it appear to be that object.

Unfortunately, this is *never* a good idea. Because the object can be 
collected at any time, you may get a nil reference from __getobj__ 
*arbitrarily* in code that tries to call methods against the given 
WeakRef. That means using WeakRef as a delegate will always result in 
unreliable code, and errors may happen for inexplicable reasons.

I believe Ruby 2.0 should eliminate WeakRef's delegation features and 
make it a simple reference holder. There's no safe way to use a weak 
reference except to grab a reference to the object, check that it is 
alive (non-nil) and then proceed with the use of the object, as follows:

obj = weakref.__getobj__
raise AppropriateError unless obj
obj.do_something
obj.do_something_else

Along with eliminating delegation, I would recommend simply making the 
get method #get, since the uglier #__getobj__ is only named that way 
because it is not delegated.
Posted by Charles Nutter (headius)
on 2013-04-16 19:54
(Received via mailing list)
Issue #6308 has been updated by headius (Charles Nutter).


Here's a patch that removes delegation from Weakref: 
https://github.com/headius/ruby/commit/431b971a147...

One test was no longer really relevant (and not adding anything), and 
others were modified to reflect this change.
----------------------------------------
Feature #6308: Eliminate delegation from WeakRef
https://bugs.ruby-lang.org/issues/6308#change-38628

Author: headius (Charles Nutter)
Status: Assigned
Priority: Normal
Assignee: matz (Yukihiro Matsumoto)
Category:
Target version:


WeakRef's delegation features are a really awful pattern that should not 
be allowed in future versions of Ruby.

WeakRef makes no guarantees as to the liveness of its contained object. 
It can be collected at any time if there are no strong references to it.

WeakRef currently uses delegation to pass method calls through to the 
contained object. This encourages a pattern where a WeakRef is passed to 
methods that expect to have a reference to the underlying object, making 
it appear to be that object.

Unfortunately, this is *never* a good idea. Because the object can be 
collected at any time, you may get a nil reference from __getobj__ 
*arbitrarily* in code that tries to call methods against the given 
WeakRef. That means using WeakRef as a delegate will always result in 
unreliable code, and errors may happen for inexplicable reasons.

I believe Ruby 2.0 should eliminate WeakRef's delegation features and 
make it a simple reference holder. There's no safe way to use a weak 
reference except to grab a reference to the object, check that it is 
alive (non-nil) and then proceed with the use of the object, as follows:

obj = weakref.__getobj__
raise AppropriateError unless obj
obj.do_something
obj.do_something_else

Along with eliminating delegation, I would recommend simply making the 
get method #get, since the uglier #__getobj__ is only named that way 
because it is not delegated.
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
No account? Register here.