Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a macro to collect outputs of a yielding method to an array #4813

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 1 addition & 4 deletions spec/std/array_spec.cr
Expand Up @@ -1409,10 +1409,7 @@ describe "Array" do
end

it "cycles N times" do
a = [] of Int32
[1, 2, 3].cycle(2) do |x|
a << x
end
a = Array.collect [1, 2, 3].cycle(2)
a.should eq([1, 2, 3, 1, 2, 3])
end

Expand Down
5 changes: 1 addition & 4 deletions spec/std/deque_spec.cr
Expand Up @@ -633,10 +633,7 @@ describe "Deque" do
end

it "cycles N times" do
a = [] of Int32
Deque{1, 2, 3}.cycle(2) do |x|
a << x
end
a = Array.collect Deque{1, 2, 3}.cycle(2)
a.should eq([1, 2, 3, 1, 2, 3])
end

Expand Down
5 changes: 1 addition & 4 deletions spec/std/dir_spec.cr
Expand Up @@ -109,10 +109,7 @@ describe "Dir" do
end

it "tests glob with a single pattern with block" do
result = [] of String
Dir.glob("#{__DIR__}/data/dir/*.txt") do |filename|
result << filename
end
result = Array.collect Dir.glob("#{__DIR__}/data/dir/*.txt")
result.sort.should eq([
"#{__DIR__}/data/dir/f1.txt",
"#{__DIR__}/data/dir/f2.txt",
Expand Down
5 changes: 1 addition & 4 deletions spec/std/yaml/serialization_spec.cr
Expand Up @@ -52,10 +52,7 @@ describe "YAML serialization" do
end

it "does Array#from_yaml with block" do
elements = [] of Int32
Array(Int32).from_yaml("---\n- 1\n- 2\n- 3\n") do |element|
elements << element
end
elements = Array.collect Array(Int32).from_yaml("---\n- 1\n- 2\n- 3\n")
elements.should eq([1, 2, 3])
end

Expand Down
30 changes: 5 additions & 25 deletions src/array.cr
Expand Up @@ -957,11 +957,7 @@ class Array(T)
# a.permutations(4) # => []
# ```
def permutations(size : Int = self.size)
ary = [] of Array(T)
each_permutation(size) do |a|
ary << a
end
ary
Array.collect each_permutation(size)
end

# Yields each possible permutation of *size* of `self`.
Expand Down Expand Up @@ -1039,11 +1035,7 @@ class Array(T)
end

def combinations(size : Int = self.size)
ary = [] of Array(T)
each_combination(size) do |a|
ary << a
end
ary
Array.collect each_combination(size)
end

def each_combination(size : Int = self.size, reuse = false) : Nil
Expand Down Expand Up @@ -1127,11 +1119,7 @@ class Array(T)
end

def repeated_combinations(size : Int = self.size)
ary = [] of Array(T)
each_repeated_combination(size) do |a|
ary << a
end
ary
Array.collect each_repeated_combination(size)
end

def each_repeated_combination(size : Int = self.size, reuse = false) : Nil
Expand Down Expand Up @@ -1175,11 +1163,7 @@ class Array(T)
end

def self.product(arrays)
result = [] of Array(typeof(arrays.first.first))
each_product(arrays) do |product|
result << product
end
result
Array.collect each_product(arrays)
end

def self.product(*arrays : Array)
Expand Down Expand Up @@ -1228,11 +1212,7 @@ class Array(T)
end

def repeated_permutations(size : Int = self.size)
ary = [] of Array(T)
each_repeated_permutation(size) do |a|
ary << a
end
ary
Array.collect each_repeated_permutation(size)
end

def each_repeated_permutation(size : Int = self.size, reuse = false) : Nil
Expand Down
6 changes: 1 addition & 5 deletions src/char.cr
Expand Up @@ -739,11 +739,7 @@ struct Char
# 'あ'.bytes # => [227, 129, 130]
# ```
def bytes
bytes = [] of UInt8
each_byte do |byte|
bytes << byte
end
bytes
Array.collect each_byte
end

# Returns this char as a string containing this char as a single character.
Expand Down
6 changes: 1 addition & 5 deletions src/dir.cr
Expand Up @@ -147,11 +147,7 @@ class Dir

# Returns an array containing all of the filenames in the given directory.
def self.entries(dirname) : Array(String)
entries = [] of String
foreach(dirname) do |filename|
entries << filename
end
entries
Array.collect foreach(dirname)
end

# Returns an array containing all of the filenames except for `.` and `..`
Expand Down
6 changes: 1 addition & 5 deletions src/dir/glob.cr
Expand Up @@ -18,11 +18,7 @@ class Dir
end

def self.glob(patterns : Enumerable(String)) : Array(String)
paths = [] of String
glob(patterns) do |path|
paths << path
end
paths
Array.collect glob(patterns)
end

def self.glob(patterns : Enumerable(String))
Expand Down
6 changes: 1 addition & 5 deletions src/file.cr
Expand Up @@ -487,11 +487,7 @@ class File < IO::FileDescriptor
# File.read_lines("foobar") # => ["foo", "bar"]
# ```
def self.read_lines(filename, encoding = nil, invalid = nil, chomp = true) : Array(String)
lines = [] of String
each_line(filename, encoding: encoding, invalid: invalid, chomp: chomp) do |line|
lines << line
end
lines
Array.collect each_line(filename, encoding: encoding, invalid: invalid, chomp: chomp)
end

# Write the given *content* to *filename*.
Expand Down
19 changes: 19 additions & 0 deletions src/macros.cr
Expand Up @@ -83,6 +83,25 @@ macro record(name, *properties)
end
end

private record TypeSentinel
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

private record does not work, better use struct directly.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right

Sucks that it doesn't work and doesn't error


class Array(T)
macro collect(expr)
%arr = [] of typeof(begin
%item = TypeSentinel.new
{{expr}} do |x|
%item = x
end
raise "Impossible" if %item.is_a? TypeSentinel
straight-shoota marked this conversation as resolved.
Show resolved Hide resolved
%item
end)
{{expr}} do |x|
%arr << x
end
%arr
end
end

# Prints a series of expressions together with their values.
# Useful for print style debugging.
#
Expand Down
18 changes: 3 additions & 15 deletions src/string.cr
Expand Up @@ -3254,11 +3254,7 @@ class String
end

def lines(chomp = true)
lines = [] of String
each_line(chomp: chomp) do |line|
lines << line
end
lines
Array.collect each_line(chomp: chomp)
end

# Splits the string after each newline and yields each line to a block.
Expand Down Expand Up @@ -3579,11 +3575,7 @@ class String
# Searches the string for instances of *pattern*,
# returning an `Array` of `Regex::MatchData` for each match.
def scan(pattern : Regex)
matches = [] of Regex::MatchData
scan(pattern) do |match|
matches << match
end
matches
Array.collect scan(pattern)
end

# Searches the string for instances of *pattern*,
Expand All @@ -3601,11 +3593,7 @@ class String
# Searches the string for instances of *pattern*,
# returning an array of the matched string for each match.
def scan(pattern : String)
matches = [] of String
scan(pattern) do |match|
matches << match
end
matches
Array.collect scan(pattern)
end

# Yields each character in the string to the block.
Expand Down