Project

General

Profile

Actions

Feature #19832

closed

Method#destructive?, UnboundMethod#destructive?

Added by sawa (Tsuyoshi Sawada) over 1 year ago. Updated over 1 year ago.

Status:
Rejected
Assignee:
-
Target version:
-
[ruby-core:114348]

Description

I propose to add destructive? property to Method and UnboundMethod instances, which shall behave like:

String.instance_method(:<<).destructive? # => true
String.instance_method(:+).destructive? # => false

One main purpose of using these classes is to inspect and make sure how a certain method behaves. Besides arity and owner, whether a method is destructive or not is one important piece of information, but currently, you cannot achieve that from Method or UnboundMethod instances.

The problem is how to implement this. It is best if this information (whether or not a method is destructive) can be extracted automatically from the method definition.

Unlike owner and arity, it may or may not be straightforward by statically analyzing the code. I think that, if a method definition defined at the ruby level does not call a destructive method anywhere within its own definition, and no dynamic method calls (send, eval, etc.) are made, then we can say that the method is non-destructive. If it does call, then the method is most likely a destructive method (it would not be destructive if the internally-called destructive method is applied to a different object. Or, we could rather call that a destructive method in the sense that it has a destructive side effect).

If doing that turns out to be difficult for some or all cases, then a practical approach for the difficult cases is to label the methods as destructive or not, manually. We can perhaps have methods Module#destructive and Module#non_destructive which take (a) symbol/string argument(s) and return the method name(s) in symbol so that they can be used like:

class A
  destructive private def some_destructive_private_method
    ...
  end
end

or

class A
  def foo; ... end
  def bar; ... end
  def baz; ... end

  non_destructive :foo, :baz
  destructive :bar
end

or

class A
  non_destructive

  def foo; ... end
  def baz; ... end

  destructive

  def bar; ... end
end

When the method is not (yet) specified whether destructive or not, the return value can be "unknown" (or :unknown or nil) by default.

String.instance_method(:<<).destructive? # => "unknown"
Actions

Also available in: Atom PDF

Like3
Like1Like0Like0Like0Like0Like0Like0Like0Like0Like2Like0Like0Like1Like0Like0Like0Like0Like2Like0Like0Like0