The Great Ruby Refinement Debate and API Minimalism


Continuing the discussion from Issue with unused definitions:

Refinements can be great and are valid code !

And the actual API namespaces are not modified for code that does not want the modifications.

The “conflict” will be transparent. The overlay (refinement) method will simply be called instead of the ancestor API method. (Ie, the actual non-refined class acts as a superclass, and the “same-named” API method can be called from the refinement method using super, if you know that the refinement overrides a 'native" method.)

The downside is that the Ruby refinement method will likely be much slower than the API method implemented in C.

How about someone running a test on the above code, and see IF rejection occurs before poo-pooing refinements (and making “Chicken Little” statements) ?

If Trimble auto-analysis tools produce false negatives on refinements, then the tools are bugged and need to be fixed.

potential potential potential potential potential potential potential potential potential potential potential
No matter how many times it is said does not make it actual.

A refinement is NEVER a conflict. It is simply a temporary overlay module creating a temporary anonymous module or subclass that is a descendant of the original. It is a graceful means of having our own private edition(s) of an API, shared library or core class, without the old monkey-patching that affected other code.

After all that hard work by the Ruby Core team to implement and improve refinements, I can’t believe this pessimism and undue caution for a real good way of avoiding the issues such as that still caused by Sketchy Physics.

The SketchUp Development Team has no good position on this matter after publishing those extensions that STILL directly monkey-patch core classes and the API, as well as littering the global objectspace with global variables that should never have been global, and many (LanguageHandler hashes) just sitting around in memory wasting space.

Monkey See - Monkey Do !

Besides, a simple test upon the original API object can be performed to see if it already responds to the method before using the refinement.

unless Sketchup::ComponentDefinition.instance_methods(false).include?(:get_used_instances)
  require File.join(__dir__,"get_used_instances")
  using GetUsedInstances

Issue with unused definitions

As to refinements, I agree with @DanRathbun’s conclusion.

They will not cause problems when used in extensions/plugins. One might consider them the equivalent of a scoped prepend.





This trunk spec is still valid for Ruby 2.0.0 (SU2014…2016,) …
but out of date for newer Ruby versions (SU2017+).

Changes include that the definition of #using() was moved from the main object (which allowed only top level calls,) to the Module class which since allows #using() calls from within module and class namespaces (and applies the refinement to those namespace, for the current code file.)

I think that the very latest Ruby versions may have fixed Kernel#send, Kernel#method and Kernel#respond_to? the so called “Indirect Method Lookup” bug.)

There may also have been other issues identified and fixed since 2.0.0. (Don’t remember offhand, wish there was a better “compendium” page for “all things refined”. :wink:

This linked trunk specification needs to be logged for updates (Rubymine?)