This tripped me up (again) today
-
@august said:
I'm using SU 15, which is supposed to have Ruby 2.0 and Dan notes that
dclone
is in 1.9, so I'm confused.What I actually said was that the
REXML
library (beginning in Ruby 1.9,) modified theArray
class, by adding thedclone
method.In order to use it, you must either precede it's use with:
require "rexml/document"
or use a refinement.(1) Using the
REXML
library:
` require "rexml/document"true
a = []
[]
a.respond_to?(:dclone)
true`(2) Refinement module:
<span class="syntaxdefault"><br />module August<br /> module DeepCopy<br /><br /> refine </span><span class="syntaxkeyword">Array do<br /> </span><span class="syntaxdefault">def dclone<br /> klone </span><span class="syntaxkeyword">= </span><span class="syntaxdefault">self</span><span class="syntaxkeyword">.clone<br /> </span><span class="syntaxdefault">klone</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">clear<br /> self</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">each</span><span class="syntaxkeyword">{|</span><span class="syntaxdefault">v</span><span class="syntaxkeyword">| </span><span class="syntaxdefault">klone </span><span class="syntaxkeyword"><< </span><span class="syntaxdefault">v</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">dclone</span><span class="syntaxkeyword">}<br /> </span><span class="syntaxdefault">klone<br /> end<br /> end </span><span class="syntaxcomment"># class Array<br /><br /> </span><span class="syntaxdefault">end </span><span class="syntaxcomment"># refinement module DeepCopy<br /></span><span class="syntaxdefault">end </span><span class="syntaxcomment"># Author's namespace<br /><br /><br /></span><span class="syntaxdefault">using August</span><span class="syntaxkeyword">;;</span><span class="syntaxdefault">DeepCopy<br /><br />module August<br /> module SomePlugin<br /> <br /> a </span><span class="syntaxkeyword">= [</span><span class="syntaxstring">"august"</span><span class="syntaxkeyword">,</span><span class="syntaxstring">"dan"</span><span class="syntaxkeyword">,</span><span class="syntaxstring">"tig"</span><span class="syntaxkeyword">]<br /> </span><span class="syntaxdefault">b </span><span class="syntaxkeyword">= </span><span class="syntaxdefault">a</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">dclone<br /> <br /> puts </span><span class="syntaxstring">"a is; #{a.inspect}"<br /> </span><span class="syntaxdefault">puts </span><span class="syntaxstring">"b is; #{b.inspect}"<br /> </span><span class="syntaxdefault">puts </span><span class="syntaxstring">"changing a[1] to \"bob\""<br /> </span><span class="syntaxdefault">a</span><span class="syntaxkeyword">[</span><span class="syntaxdefault">1</span><span class="syntaxkeyword">]= </span><span class="syntaxstring">"bob"<br /> </span><span class="syntaxdefault">puts </span><span class="syntaxstring">"a is; #{a.inspect}"<br /> </span><span class="syntaxdefault">puts </span><span class="syntaxstring">"b is; #{b.inspect}"<br /><br /> </span><span class="syntaxdefault">end </span><span class="syntaxcomment"># module SomePlugin<br /></span><span class="syntaxdefault">end </span><span class="syntaxcomment"># Author's namespace<br /> </span><span class="syntaxdefault"></span>
Any call to
using()
must occur within theTOPLEVEL_BINDING
.
This restriction has been removed in later versions of Ruby 2.2+, and the experimental warning that is output on calls torefine
has also been removed. (Ie, refinements are no longer experimental and calls tousing
can happen inside specificmodule
andclass
scopes.)If you want to see that all the elements of the arrays are different objects, you can iterate them and compare their object id numbers.
-
Thanks Dan,
So refine allows me to add my own operators to an existing class? That's a sweet (and dangerous) concept.
I'll have to put that on the back burner for now. I'm still working on basic Ruby.
-
@august said:
So refine allows me to add my own operators to an existing class? That's a sweet (and dangerous) concept.
Refinements do not affect other people's scripts that do not "use" the refinement module. (They are only valid within the file that has the
using
call.) -
Another basic concept is the mixin module, which uses
include()
andextend()
.In this case, in order to affect only the array you are using, you need to only "extend" the specific array instance object.
So, assume you have previously loaded a mixin module thus:
<span class="syntaxdefault">module August<br /> module DeepCopy<br /><br /> def dclone<br /> klone </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> self</span><span class="syntaxkeyword">.clone<br /></span><span class="syntaxdefault"> klone</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">clear<br /> self</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">each</span><span class="syntaxkeyword">{|</span><span class="syntaxdefault">v</span><span class="syntaxkeyword">|</span><span class="syntaxdefault"> klone </span><span class="syntaxkeyword"><<</span><span class="syntaxdefault"> v</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">dclone</span><span class="syntaxkeyword">}<br /></span><span class="syntaxdefault"> klone<br /> end<br /><br /> end </span><span class="syntaxcomment"># mixin module DeepCopy<br /></span><span class="syntaxdefault">end </span><span class="syntaxcomment"># Author's namespace </span><span class="syntaxdefault"></span>
Then you need to extend a specific array instance:
<span class="syntaxdefault">a </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">[</span><span class="syntaxstring">"august"</span><span class="syntaxkeyword">,</span><span class="syntaxstring">"dan"</span><span class="syntaxkeyword">,</span><span class="syntaxstring">"tig"</span><span class="syntaxkeyword">]<br /><br /></span><span class="syntaxdefault">a</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">extend</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">August</span><span class="syntaxkeyword">;;</span><span class="syntaxdefault">DeepCopy</span><span class="syntaxkeyword">)<br /><br /></span><span class="syntaxdefault">b </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> a</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">dclone</span>
-
Back to TIG's comment about plural vs. singular names for arrays, here is the way I'm naming things. In this context, the singular terms seem to work better for me, probably because I think of it as the mathematical notation P[sub:2dctu78y]0[/sub:2dctu78y], P[sub:2dctu78y]1[/sub:2dctu78y], ... P[sub:2dctu78y]N[/sub:2dctu78y].
=begin point[N] x-------------x point[0] angle[0] = angle_between vector[N], vector[0] vector[N] \ vector[N] = point[N], point[0] \ \ vector[0] \ vector[0] = point[0], point[1] \ x point[1] angle[1] = angle_between vector[0], vector[1] / vector[1] / vector[1] = point[1], point[2] / / / x point[2] angle[2] = angle_between vector[1], vector[2] =end
Advertisement