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

Documenting Indexable#zip and Indexable#zip? methods. #5734

Conversation

rodrigopinto
Copy link
Contributor

This PR is for adding a documentation for Indexable#zip methods. It closes #5732.

  • Add documentation to Indexable#zip(other : Indexable)
  • Add documentation to Indexable#zip(other : Indexable) &block
  • Add documentation to Indexable#zip?(other : Indexable)
  • Add documentation to Indexable#zip?(other : Indexable) &block

src/indexable.cr Outdated
@@ -412,24 +412,80 @@ module Indexable(T)
indexes.map { |index| self[index] }
end

# Calls the given block once for each index in `self`, passing `self`
Copy link
Contributor

Choose a reason for hiding this comment

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

Calls the given block for each index in self, passing in the element at that index in self and the element at the same index in other.

?

Also make sure to note that this method raises.

src/indexable.cr Outdated
# a = [1, 2, 3]
# b = ["a", "b", "c"]
#
# a.zip(b) { |x,y| puts "[ #{x} -- #{y} ]" }
Copy link
Contributor

Choose a reason for hiding this comment

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

just "#{x} -- #{y}"? Not sure why we need the [].

src/indexable.cr Outdated
def zip(other : Indexable)
each_with_index do |elem, i|
yield elem, other[i]
end
end

# Returns an `Array` of Tuples populated with the *N* index
# element from `self` and *N* index element from `other`.
Copy link
Contributor

Choose a reason for hiding this comment

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

Returns an Array of tuples populated with the ith indexed element from self followed by the ith indexed element from other, for all i 0..self.size - 1

Maybe that needs more tweaking.

src/indexable.cr Outdated
# Returns an `Array` of Tuples populated with the *N* index
# element from `self` and *N* index element from `other`.
#
# Raises IndexError if `other` has no index corresponding to `self`.
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd mention that this happens when other is shorter than self.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Makes sense. It makes the sentence more clear.

src/indexable.cr Outdated
def zip(other : Indexable(U)) forall U
pairs = Array({T, U}).new(size)
zip(other) { |x, y| pairs << {x, y} }
pairs
end

# Returns an `Array` of Tuples populated with the *N* element from `self`
# and *N* element from `other`.
Copy link
Contributor

Choose a reason for hiding this comment

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

ditto from above

src/indexable.cr Outdated
def zip(other : Indexable(U)) forall U
pairs = Array({T, U}).new(size)
zip(other) { |x, y| pairs << {x, y} }
pairs
end

# Returns an `Array` of Tuples populated with the *N* element from `self`
# and *N* element from `other`.
# It adds *nil* when `other` returns outside the range for the given index.
Copy link
Contributor

Choose a reason for hiding this comment

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

If other has no index corresponding to self (when other is shorter than self), the missing element is substituted with nil.

src/indexable.cr Outdated
# a = [1, 2, 3]
# b = [4, 5]
#
# a.zip(b) # => [{1, 1}, {2, 2}, {3, nil}]
Copy link
Contributor

Choose a reason for hiding this comment

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

{1, 4}, {2, 5}, {3, nil}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ops. 😬

src/indexable.cr Outdated
def zip?(other : Indexable)
each_with_index do |elem, i|
yield elem, other[i]?
end
end

# Calls the given block once for each index in `self`, passing `self`
# and `other` index element as parameter.
Copy link
Contributor

Choose a reason for hiding this comment

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

Ditto from the first comment.

src/indexable.cr Outdated
def zip?(other : Indexable)
each_with_index do |elem, i|
yield elem, other[i]?
end
end

# Calls the given block once for each index in `self`, passing `self`
# and `other` index element as parameter.
# It adds *nil* when `other` returns outside the range for a index.
Copy link
Contributor

Choose a reason for hiding this comment

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

Adapt this to be similar to the phrase of the other zip? method.

src/indexable.cr Outdated
# a = {1, 2, 3}
# b = {"a", "b"}
#
# a.zip?(b) { |x,y| puts "[ #{x} -- #{y} ]" }
Copy link
Contributor

Choose a reason for hiding this comment

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

ditto

src/indexable.cr Outdated
@@ -412,24 +412,80 @@ module Indexable(T)
indexes.map { |index| self[index] }
end

# Calls the given block once for each index in `self`, passing `self`
Copy link
Member

Choose a reason for hiding this comment

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

`self` and `other` index element is ambiguous and difficult to understand. Maybe `{self[i], other[i]}` for each index?

src/indexable.cr Outdated
# [ 1 -- a ]
# [ 2 -- b ]
# [ 3 -- c ]
#```
def zip(other : Indexable)
Copy link
Member

Choose a reason for hiding this comment

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

For documentation purposes, I would prefer to have the block argument in the method signature even if it is not used as a captured block: This makes it clear that this method definition is expected to be called with a block and it shows the block types:

def zip(other : Indexable(U), &block : T, U ->) forall U

Copy link
Contributor Author

Choose a reason for hiding this comment

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

👍 Completely agree with your point, it makes extremely more readable!

It also brings me a question:

The Indexable module is used as a mixin in other classes/structs what adds to them the zip methods behavior in addition to others. Currently only Array#zip(?) has tests covering it. Would make sense to move the specs to src/std/indexable_spec.cr instead of src/std/array_spec.cr?

src/indexable.cr Outdated
# a.zip(b) { |x,y| puts "[ #{x} -- #{y} ]" }
# ```
#
# produces:
Copy link
Member

Choose a reason for hiding this comment

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

The example would be more condensed if t was in one code block and the printed output just commented lines.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It is possible, I firstly did like you mentioned, but after some research, I followed the example what exists at src/dir.cr to keep the consistency.

Copy link
Member

Choose a reason for hiding this comment

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

I'm not sure consistency is that important for this and besides, we can change the example for Dir as well...
It's just an unnecessary division between the example code and output. IMHO it should be as condensed as possible For examples that cover multiple files, I usually just print them in one code block and use comments to indicate different files. This keeps things compact and connected.

src/indexable.cr Outdated
# b = ["a", "b", "c"]
#
# a.zip(b) # => [{1, "a"}, {2, "b"}, {3, "c"}]
# ```
def zip(other : Indexable(U)) forall U
Copy link
Member

Choose a reason for hiding this comment

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

Also for documentation purposes, I would prefer to state the return type explicitly:

def zip(other : Indexable(U)) : Array({T, U}) forall U

src/indexable.cr Outdated
def zip(other : Indexable)
each_with_index do |elem, i|
yield elem, other[i]
end
end

# Returns an `Array` of Tuples populated with the *N* index
Copy link
Member

Choose a reason for hiding this comment

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

better: nth index.
Or like above: `Array` of tuples `{self[i], other[i]}` for each index.

src/indexable.cr Outdated
# Returns an `Array` of Tuples populated with the *N* index
# element from `self` and *N* index element from `other`.
#
# Raises IndexError if `other` has no index corresponding to `self`.
Copy link
Member

Choose a reason for hiding this comment

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

Maybe Raises `IndexError` if `self` has more elements than `other`.

src/indexable.cr Outdated
def zip(other : Indexable(U)) forall U
pairs = Array({T, U}).new(size)
zip(other) { |x, y| pairs << {x, y} }
pairs
end

# Returns an `Array` of Tuples populated with the *N* element from `self`
# and *N* element from `other`.
# It adds *nil* when `other` returns outside the range for the given index.
Copy link
Member

Choose a reason for hiding this comment

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

This sentence doesn't really make sense. Perhaps: If `self` has more entries than `other`, missing values are filled up with `nil`.

src/indexable.cr Outdated
# a = [1, 2, 3]
# b = [4, 5]
#
# a.zip(b) # => [{1, 1}, {2, 2}, {3, nil}]
Copy link
Member

Choose a reason for hiding this comment

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

This result is incorrect, with the given sample data it would be [{1, 4}, {2, 5}, {3, nil}]. But it would probably be best to adjust the values in b.

src/indexable.cr Outdated
# b = [4, 5]
#
# a.zip(b) # => [{1, 1}, {2, 2}, {3, nil}]
# ```
def zip?(other : Indexable)
Copy link
Member

Choose a reason for hiding this comment

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

ditto:

def zip(other : Indexable(U), &block : T, U? ->) forall U

src/indexable.cr Outdated
# [ 2 -- b ]
# [ 3 -- ]
# ```
#
def zip?(other : Indexable(U)) forall U
Copy link
Member

Choose a reason for hiding this comment

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

ditto:

def zip(other : Indexable(U)) : Array({T, U?}) forall U

@rodrigopinto rodrigopinto force-pushed the rp-add-docs-to-indexable-zip-methods branch from dc59ecf to 94c189d Compare February 24, 2018 09:06
RX14
RX14 previously requested changes Feb 25, 2018
src/indexable.cr Outdated
#
# ```
# a = [1, 2, 3]
# b = ["a", "b", "c"]
#
# a.zip(b) { |x,y| puts "[ #{x} -- #{y} ]" }
# a.zip(b) { |x,y| puts "#{x} -- #{y}" }
# => 1 --- 5
Copy link
Contributor

Choose a reason for hiding this comment

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

this should be 1 -- a and ditto.

src/indexable.cr Outdated
# ```
def zip?(other : Indexable)
def zip?(other : Indexable, &block : T, U ->) forall U
Copy link
Contributor

Choose a reason for hiding this comment

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

Indexable(U), then T, U? ->

src/indexable.cr Outdated
def zip?(other : Indexable(U)) forall U
# a.zip?(b) # => [{1, 4}, {2, 5}, {3, nil}]
# ```
def zip?(other : Indexable(U) : Array({T, U})) forall U
Copy link
Contributor

Choose a reason for hiding this comment

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

The syntax is malformed here.

Also, should be Array({T, U?})

@RX14 RX14 dismissed their stale review February 25, 2018 13:36

Oops, looks like I reviewed an old diff

src/indexable.cr Outdated
#
# a.zip(b) # => [{1, "a"}, {2, "b"}, {3, "c"}]
# ```
def zip(other : Indexable(U)) : Array({T, U?}) forall U
Copy link
Contributor

Choose a reason for hiding this comment

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

This should be Array({T, U}) still, since it's zip not zip?. THis is causing the compile errors.

src/indexable.cr Outdated
# a.zip(b) # => [{1, "a"}, {2, "b"}, {3, "c"}]
# ```
def zip(other : Indexable(U)) : Array({T, U?}) forall U
pairs = Array({T, U?}).new(size)
Copy link
Contributor

Choose a reason for hiding this comment

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

ditto.

@rodrigopinto
Copy link
Contributor Author

@RX14 tests are passing, if everything looks fine, I will squash the commits into a single one.

@rodrigopinto rodrigopinto force-pushed the rp-add-docs-to-indexable-zip-methods branch from 86961b0 to 4666d56 Compare February 25, 2018 22:34
src/indexable.cr Outdated
# b = ["a", "b", "c"]
#
# a.zip(b) { |x,y| puts "#{x} -- #{y}" }
#
Copy link
Member

Choose a reason for hiding this comment

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

The code block needs to be closed.

src/indexable.cr Outdated
each_with_index do |elem, i|
yield elem, other[i]?
end
end

def zip?(other : Indexable(U)) forall U
# Returns an `Array` of tuples populated with the _i_th indexed element from
Copy link
Member

Choose a reason for hiding this comment

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

You used *i*th in the other method's doc.

@RX14
Copy link
Contributor

RX14 commented Jun 8, 2018

format failure

@RX14
Copy link
Contributor

RX14 commented Jun 10, 2018

I think this needs a rebase onto master to fix CI

@rodrigopinto rodrigopinto force-pushed the rp-add-docs-to-indexable-zip-methods branch from 6e2d3c2 to 135970f Compare June 10, 2018 18:07
@rodrigopinto
Copy link
Contributor Author

@RX14 All green. 💚 I will squash it later to get it merged.

@rodrigopinto rodrigopinto force-pushed the rp-add-docs-to-indexable-zip-methods branch from 135970f to c61d580 Compare June 13, 2018 17:37
@rodrigopinto
Copy link
Contributor Author

@RX14 squashed!

@bcardiff bcardiff merged commit bb89684 into crystal-lang:master Jun 13, 2018
@bcardiff bcardiff added this to the 0.25.1 milestone Jun 13, 2018
@bcardiff
Copy link
Member

Thanks @rodrigopinto !

@rodrigopinto rodrigopinto deleted the rp-add-docs-to-indexable-zip-methods branch June 14, 2018 04:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add documentation for Indexable#zip methods
5 participants