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: 97c062e48100
Choose a base ref
...
head repository: opal/opal
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 0bc0dc13a88b
Choose a head ref
  • 3 commits
  • 5 files changed
  • 1 contributor

Commits on Oct 25, 2013

  1. Add Opal::Type.coerce_to helper

    meh committed Oct 25, 2013
    Copy the full SHA
    cbffd7c View commit details
  2. Make Array#fill compliant

    meh committed Oct 25, 2013
    Copy the full SHA
    de34c84 View commit details
  3. Copy the full SHA
    0bc0dc1 View commit details
Showing with 107 additions and 32 deletions.
  1. +88 −32 corelib/array.rb
  2. +14 −0 corelib/opal.rb
  3. +2 −0 spec/filters/unsupported/frozen.rb
  4. +2 −0 spec/filters/unsupported/immutable_strings.rb
  5. +1 −0 spec/rubyspecs
120 changes: 88 additions & 32 deletions corelib/array.rb
Original file line number Diff line number Diff line change
@@ -25,11 +25,7 @@ def self.new(size = nil, obj = nil, &block)
return size.to_ary
end

unless size.respond_to? :to_int
raise TypeError, "no implicit conversion of #{size.class} into Integer"
end

size = size.to_int
size = Opal::Type.coerce_to size, Integer, :to_int

if `size < 0`
raise ArgumentError, "negative array size"
@@ -69,10 +65,8 @@ def self.try_convert(obj)
def &(other)
if Array === other
other = other.to_a
elsif other.respond_to? :to_ary
other = other.to_ary
else
raise TypeError, "no implicit conversion of #{other.class} into Array"
other = Opal::Type.coerce_to other, Array, :to_ary
end

%x{
@@ -105,7 +99,7 @@ def *(other)
raise TypeError, "no implicit conversion of #{other.class} into Integer"
end

other = other.to_int
other = Opal::Type.coerce_to other, Integer, :to_int

if `other < 0`
raise ArgumentError, "negative argument"
@@ -125,10 +119,8 @@ def *(other)
def +(other)
if Array === other
other = other.to_a
elsif other.respond_to? :to_ary
other = other.to_ary
else
raise TypeError, "no implicit conversion of #{other.class} into Array"
other = Opal::Type.coerce_to other, Array, :to_ary
end

`self.concat(other)`
@@ -137,10 +129,8 @@ def +(other)
def -(other)
if Array === other
other = other.to_a
elsif other.respond_to? :to_ary
other = other.to_ary
else
raise TypeError, "no implicit conversion of #{other.class} into Array"
other = Opal::Type.coerce_to other, Array, :to_ary
end

return [] if `self.length === 0`
@@ -357,11 +347,7 @@ def cycle(n = nil, &block)
end
end
else
unless n.respond_to? :to_int
raise TypeError, "no implicit conversion of #{n.class} into Integer"
end

cycles = n.to_int
cycles = Opal::Type.coerce_to n, Integer, :to_int

unless Integer === cycles
raise TypeError, "can't convert #{n.class} into Integer (#{n.class}#to_int gives #{cycles.class}"
@@ -588,19 +574,91 @@ def fetch(index, defaults = undefined, &block)
}
end

def fill(obj = undefined, &block)
%x{
if (block !== nil) {
for (var i = 0, length = #{self}.length; i < length; i++) {
#{self}[i] = block(i);
def fill(*args, &block)
if block
if `args.length > 2`
raise ArgumentError, "wrong number of arguments (#{args.length} for 0..2)"
end

one, two = args
else
if `args.length == 0`
raise ArgumentError, "wrong number of arguments (0 for 1..3)"
elsif `args.length > 3`
raise ArgumentError, "wrong number of arguments (#{args.length} for 1..3)"
end

obj, one, two = args
end

if Range === one
raise TypeError, "length invalid with range" if two

left = Opal::Type.coerce_to one.begin, Integer, :to_int
`left += #@length` if `left < 0`
raise RangeError, "#{one.inspect} out of range" if `left < 0`

right = Opal::Type.coerce_to one.end, Integer, :to_int
`right += #@length` if `right < 0`
`right += 1` unless one.exclude_end?

return self if `right <= left`
elsif one
left = Opal::Type.coerce_to one, Integer, :to_int
`left += #@length` if `left < 0`
left = 0 if `left < 0`

if two
right = Opal::Type.coerce_to two, Integer, :to_int

return self if `right == 0`

`right += left`
else
right = @length
end
else
left = 0
right = @length
end

if `right > 2147483648`
raise RangeError, "bignum too big to convert into `long'"
elsif `right >= 536870910`
raise ArgumentError, "argument too big"
end

if `left > #@length`
%x{
for (var i = #@length; i < right; i++) {
self[i] = nil;
}
}
else {
for (var i = 0, length = #{self}.length; i < length; i++) {
#{self}[i] = obj;
end

if `right > #@length`
@length = right
end

if block
%x{
for (var length = #@length; left < right; left++) {
var value = block(left);
if (value === $breaker) {
return $breaker.$v;
}
self[left] = value;
}
}
}
else
%x{
for (var length = #@length; left < right; left++) {
self[left] = #{obj};
}
}
end

self
end
@@ -1172,10 +1230,8 @@ def transpose
each {|row|
if Array === row
row = row.to_a
elsif row.respond_to? :to_ary
row = row.to_ary
else
raise TypeError, "no implicit conversion of #{row.class} into Array"
row = Opal::Type.coerce_to row, Array, :to_ary
end

max ||= `row.length`
14 changes: 14 additions & 0 deletions corelib/opal.rb
Original file line number Diff line number Diff line change
@@ -43,3 +43,17 @@
RUBY_VERSION = '1.9.3'
RUBY_ENGINE_VERSION = '0.4.4'
RUBY_RELEASE_DATE = '2013-08-13'

module Opal
module Type
def self.coerce_to(object, type, method)
return object if type === object

unless object.respond_to? method
raise TypeError, "no implicit conversion of #{object.class} into #{type}"
end

object.__send__ method
end
end
end
2 changes: 2 additions & 0 deletions spec/filters/unsupported/frozen.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
opal_filter "Object#frozen" do
fails "Array#fill raises a RuntimeError on a frozen array"
fails "Array#fill raises a RuntimeError on an empty frozen array"
fails "Array#frozen? returns true if array is frozen"
fails "Array#frozen? returns false for an array being sorted by #sort"
fails "Array#unshift raises a RuntimeError on a frozen array when the array is modified"
2 changes: 2 additions & 0 deletions spec/filters/unsupported/immutable_strings.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
opal_filter "immutable strings" do
fails "Array#fill does not replicate the filler"

fails "Hash literal freezes string keys on initialization"
end
1 change: 1 addition & 0 deletions spec/rubyspecs
Original file line number Diff line number Diff line change
@@ -27,6 +27,7 @@ core/array/empty_spec
core/array/eql_spec
core/array/equal_value_spec
core/array/fetch_spec
core/array/fill_spec
core/array/first_spec
core/array/flatten_spec
core/array/frozen_spec