Skip to content

Commit d832027

Browse files
committed
Implement correct cloning behaviour for Range.
1 parent 1010f95 commit d832027

File tree

3 files changed

+43
-1
lines changed

3 files changed

+43
-1
lines changed

src/main/java/org/truffleruby/core/range/RangeNodes.java

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ protected Object eachObject(RubyObjectRange range) {
192192

193193
}
194194

195-
@CoreMethod(names = { "dup", "clone" })
195+
@CoreMethod(names = "dup")
196196
public abstract static class DupNode extends UnaryCoreMethodNode {
197197

198198
// NOTE(norswap): This is a hack, as it doesn't copy the ivars.
@@ -241,6 +241,37 @@ protected RubyObjectRange dup(RubyObjectRange range) {
241241
}
242242
}
243243

244+
@CoreMethod(names = "clone")
245+
public abstract static class CloneNode extends UnaryCoreMethodNode {
246+
247+
// NOTE(norswap): This is a hack, as it doesn't copy the ivars.
248+
// We do copy the logical class (but not the singleton class, to be MRI compatible).
249+
250+
@Specialization
251+
protected RubyIntRange cloneIntRange(RubyIntRange range) {
252+
return new RubyIntRange(range);
253+
}
254+
255+
@Specialization
256+
protected RubyLongRange dupLongRange(RubyLongRange range) {
257+
return new RubyLongRange(range);
258+
}
259+
260+
@Specialization
261+
protected RubyObjectRange dup(RubyObjectRange range) {
262+
final RubyClass logicalClass = range.getLogicalClass();
263+
final RubyObjectRange copy = new RubyObjectRange(
264+
logicalClass,
265+
getLanguage().objectRangeShape,
266+
range.excludedEnd,
267+
range.begin,
268+
range.end,
269+
range.frozen);
270+
AllocationTracing.trace(copy, this);
271+
return copy;
272+
}
273+
}
274+
244275
@CoreMethod(names = "end")
245276
public abstract static class EndNode extends CoreMethodArrayArgumentsNode {
246277

src/main/java/org/truffleruby/core/range/RubyIntRange.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,12 @@ public RubyIntRange(boolean excludedEnd, int begin, int end) {
3131
this.excludedEnd = excludedEnd;
3232
this.begin = begin;
3333
this.end = end;
34+
}
3435

36+
public RubyIntRange(RubyIntRange other) {
37+
this.excludedEnd = other.excludedEnd;
38+
this.begin = other.begin;
39+
this.end = other.end;
3540
}
3641

3742
@ExportMessage

src/main/java/org/truffleruby/core/range/RubyLongRange.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@ public RubyLongRange(boolean excludedEnd, long begin, long end) {
3333
this.end = end;
3434
}
3535

36+
public RubyLongRange(RubyLongRange other) {
37+
this.excludedEnd = other.excludedEnd;
38+
this.begin = other.begin;
39+
this.end = other.end;
40+
}
41+
3642
@ExportMessage
3743
public boolean hasIterator() {
3844
return true;

0 commit comments

Comments
 (0)