diff --git a/spec/std/enumerable_spec.cr b/spec/std/enumerable_spec.cr index 0bcbac725cb5..4ff17d672687 100644 --- a/spec/std/enumerable_spec.cr +++ b/spec/std/enumerable_spec.cr @@ -1,6 +1,25 @@ require "spec" require "spec/helpers/iterate" +module SomeInterface; end + +private record One do + include SomeInterface +end + +private record Two do + include SomeInterface +end + +private struct InterfaceEnumerable + include Enumerable(SomeInterface) + + def each(&) + yield One.new + yield Two.new + end +end + private class SpecEnumerable include Enumerable(Int32) @@ -132,13 +151,17 @@ describe "Enumerable" do end describe "to_a" do - context "with a block" do + it "with a block" do SpecEnumerable.new.to_a { |e| e*2 }.should eq [2, 4, 6] end - context "without a block" do + it "without a block" do SpecEnumerable.new.to_a.should eq [1, 2, 3] end + + it "without a block of an interface type" do + InterfaceEnumerable.new.to_a.should eq [One.new, Two.new] + end end describe "#to_set" do @@ -1456,6 +1479,10 @@ describe "Enumerable" do {'c' => 1, 'r' => 2, 'y' => 2, 's' => 1, 't' => 1, 'a' => 1, 'l' => 1, 'u' => 1, 'b' => 1} ) end + + it "tallies an interface type" do + InterfaceEnumerable.new.tally.should eq({One.new => 1, Two.new => 1}) + end end end diff --git a/spec/std/indexable_spec.cr b/spec/std/indexable_spec.cr index 75a20f14e521..2d1ab60c0846 100644 --- a/spec/std/indexable_spec.cr +++ b/spec/std/indexable_spec.cr @@ -1,6 +1,33 @@ require "spec" require "spec/helpers/iterate" +module OtherInterface; end + +private record Three do + include OtherInterface +end + +private record Four do + include OtherInterface +end + +private struct InterfaceIndexable + include Indexable(OtherInterface) + + def size + 2 + end + + def unsafe_fetch(index : Int) : OtherInterface + case index + when 0 then Three.new + when 1 then Four.new + else + raise "" + end + end +end + private class SafeIndexable include Indexable(Int32) @@ -818,4 +845,10 @@ describe Indexable do it_iterates "#each_repeated_combination", [[1, 1, 1, 1], [1, 1, 1, 2], [1, 1, 2, 2], [1, 2, 2, 2], [2, 2, 2, 2]], SafeIndexable.new(2, 1).each_repeated_combination(4) end end + + describe "#to_a" do + it "without a block of an interface type" do + InterfaceIndexable.new.to_a.should eq [Three.new, Four.new] + end + end end diff --git a/src/enumerable.cr b/src/enumerable.cr index 9a1aad3debd0..ff49de1ff308 100644 --- a/src/enumerable.cr +++ b/src/enumerable.cr @@ -1970,7 +1970,7 @@ module Enumerable(T) # ["a", "b", "c", "b"].tally # => {"a"=>1, "b"=>2, "c"=>1} # ``` def tally : Hash(T, Int32) - tally_by(&.itself) + tally_by(Hash(T, Int32).new, &.itself) end # Tallies the collection. Accepts a *hash* to count occurrences. @@ -1994,7 +1994,9 @@ module Enumerable(T) # (1..5).to_a # => [1, 2, 3, 4, 5] # ``` def to_a : Array(T) - to_a(&.itself) + ary = [] of T + each { |e| ary << e } + ary end # Returns an `Array` with the results of running *block* against each element of the collection. diff --git a/src/indexable.cr b/src/indexable.cr index bec815ee3d7f..d39ddaaef197 100644 --- a/src/indexable.cr +++ b/src/indexable.cr @@ -693,6 +693,17 @@ module Indexable(T) end end + # Returns an `Array` with all the elements in the collection. + # + # ``` + # {1, 2, 3}.to_a # => [1, 2, 3] + # ``` + def to_a : Array(T) + ary = Array(T).new(size) + each { |e| ary << e } + ary + end + # Returns an `Array` with the results of running *block* against each element of the collection. # # ```