Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: opal/opal
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 5328b8c8c870
Choose a base ref
...
head repository: opal/opal
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: ce378612c905
Choose a head ref
  • 2 commits
  • 2 files changed
  • 1 contributor

Commits on Aug 2, 2015

  1. Copy the full SHA
    1ed2e9e View commit details
  2. Merge pull request #1040 from vais/array

    Make Array #&, #|, #-, #uniq, #uniq! use `Hash` to match MRI semantics
    vais committed Aug 2, 2015
    Copy the full SHA
    ce37861 View commit details
Showing with 44 additions and 73 deletions.
  1. +35 −67 opal/corelib/array.rb
  2. +9 −6 opal/corelib/hash.rb
102 changes: 35 additions & 67 deletions opal/corelib/array.rb
Original file line number Diff line number Diff line change
@@ -73,20 +73,15 @@ def &(other)
end

%x{
var result = [],
others = {},
i, length, item, hash;
var result = [], hash = #{{}}, i, length, item;
for (i = 0, length = other.length; i < length; i++) {
item = other[i];
others[item.$hash()] = item;
Opal.hash_put(hash, other[i], true);
}
for (i = 0, length = self.length; i < length; i++) {
item = self[i];
hash = item.$hash();
if (others.hasOwnProperty(hash) && (item.$object_id() === others[hash].$object_id() || #{`item`.eql?(`others[hash]`)})) {
delete others[hash];
if (Opal.hash_delete(hash, item) !== undefined) {
result.push(item);
}
}
@@ -103,34 +98,17 @@ def |(other)
end

%x{
var result = [],
seen = {}, i, length, item, item_hash;
var hash = #{{}}, i, length, item;
for (i = 0, length = self.length; i < length; i++) {
item = self[i];
item_hash = item.$hash();
if (!seen.hasOwnProperty(item_hash)) {
seen[item_hash] = item;
result.push(item);
}
Opal.hash_put(hash, self[i], true);
}
for (i = 0, length = other.length; i < length; i++) {
item = other[i];
item_hash = item.$hash();
if (seen.hasOwnProperty(item_hash)) {
if (!(item.$object_id() === seen[item_hash].$object_id() || #{`item`.eql?(`seen[item_hash]`)})) {
result.push(item);
}
} else {
seen[item_hash] = item;
result.push(item);
}
Opal.hash_put(hash, other[i], true);
}
return result;
return hash.$keys();
}
end

@@ -179,25 +157,17 @@ def -(other)
return clone if `other.length === 0`

%x{
var seen = {},
result = [], i, length, item, hash;
var result = [], hash = #{{}}, i, length, item;
for (i = 0, length = other.length; i < length; i++) {
item = other[i];
hash = item.$hash();
seen[hash] = item;
Opal.hash_put(hash, other[i], true);
}
for (i = 0, length = self.length; i < length; i++) {
item = self[i];
hash = item.$hash();
if (seen.hasOwnProperty(hash)) {
if (item.$object_id() === seen[hash].$object_id()) { continue; }
if (#{`item`.eql?(`seen[hash]`)}) { continue; }
if (Opal.hash_get(hash, item) === undefined) {
result.push(item);
}
result.push(item);
}
return result;
@@ -1922,7 +1892,7 @@ def to_h
}
key = ary[0];
val = ary[1];
hash.$store(key, val);
Opal.hash_put(hash, key, val);
}
return hash;
@@ -1961,42 +1931,40 @@ def transpose

def uniq(&block)
%x{
var result = [],
seen = {}, i, length, item, hash;
var hash = #{{}}, i, length, item, key;
for (i = 0, length = self.length; i < length; i++) {
item = block === nil ? self[i] : Opal.yield1(block, self[i]);
hash = item.$hash();
if (seen.hasOwnProperty(hash)) {
if (item.$object_id() === seen[hash].$object_id() || #{`item`.eql?(`seen[hash]`)}) {
continue;
if (block === nil) {
for (i = 0, length = self.length; i < length; i++) {
item = self[i];
if (Opal.hash_get(hash, item) === undefined) {
Opal.hash_put(hash, item, item);
}
}
}
else {
for (i = 0, length = self.length; i < length; i++) {
item = self[i];
key = Opal.yield1(block, item);
if (Opal.hash_get(hash, key) === undefined) {
Opal.hash_put(hash, key, item);
}
}
seen[hash] = item;
result.push(self[i]);
}
return result;
return hash.$values();
}
end

def uniq!(&block)
%x{
var original = self.length,
seen = {}, i, length, item, hash;
for (i = 0, length = original; i < length; i++) {
item = block === nil ? self[i] : Opal.yield1(block, self[i]);
hash = item.$hash();
var original_length = self.length, hash = #{{}}, i, length, item, key;
if (!seen.hasOwnProperty(hash)) {
seen[hash] = item;
continue;
}
for (i = 0, length = original_length; i < length; i++) {
item = self[i];
key = (block === nil ? item : Opal.yield1(block, item));
if (!(item.$object_id() === seen[hash].$object_id() || #{`item`.eql?(`seen[hash]`)})) {
if (Opal.hash_get(hash, key) === undefined) {
Opal.hash_put(hash, key, item);
continue;
}
@@ -2005,7 +1973,7 @@ def uniq!(&block)
i--;
}
return self.length === original ? nil : self;
return self.length === original_length ? nil : self;
}
end

15 changes: 9 additions & 6 deletions opal/corelib/hash.rb
Original file line number Diff line number Diff line change
@@ -592,15 +592,19 @@ def keep_if(&block)

def keys
%x{
var keys = self.keys.slice();
var result = [];
for (var i = 0, length = keys.length, key; i < length; i++) {
for (var i = 0, keys = self.keys, length = keys.length, key; i < length; i++) {
key = keys[i];
if (!key.$$is_string) { keys[i] = key.key; }
if (key.$$is_string) {
result.push(key);
} else {
result.push(key.key);
}
}
return keys;
return result;
}
end

@@ -931,15 +935,14 @@ def values
%x{
var result = [];
for (var i = 0, keys = self.keys, length = keys.length, key, value; i < length; i++) {
for (var i = 0, keys = self.keys, length = keys.length, key; i < length; i++) {
key = keys[i];
if (key.$$is_string) {
result.push(self.smap[key]);
} else {
result.push(key.value);
}
}
return result;