Receiver reference method "Array # each"

I am iterating over an array and I am wondering if there is a shorthand reference to the method receiver #each

(or #each_with_index

) from the iteration.

self

returns main

.

+1


source to share


4 answers


You can just link to it:



my_thing.each {|one_thing| puts my_thing }

      

+2


source


This is very similar to the answer I gave here at fooobar.com/questions/2423873 / ... , but slightly different.

First, you can create an self

array-bound scope and then execute each

on that scope:

[1].instance_exec do
  # in this scope, self is the array
  # thus we can use just 'each' because the self is inferred
  each do |x|
    # note that since 'class' is a special keyword,
    # it needs to be explicitly namespaced on self
    puts self.class, x
  end
end
# => prints Array, 1

      



You can create a utility function for this if you like:

def bound_each(enumerable, &blk)
  enumerable.instance_exec { each &blk }
end
bound_each([1]) { |x| puts self.class, x }
# prints Array, 1

      

+2


source


You can call your method each

in a block Object#tap

and refer to the original receiver as such.

[1, 2, 3].tap { |i| i.each { |j| p i.dup << j } }
# [1, 2, 3, 1]
# [1, 2, 3, 2]
# [1, 2, 3, 3]
#=> [1, 2, 3] 

      

This is the receiving object [1, 2, 3]

and is passed to a block variable i

that we can use locally or in nested scopes like each

block.

Avoid modifying the receiving object, otherwise you might get unwanted results like an infinite array. Use dup

can eliminate this possibility.

+1


source


This is an interesting question. This is not possible as far as I know - the closest I can do is use inject

(or reduce

) and explicitly pass the receiver as an argument. A bit pointless, but there might be a use case for it that I don't see:

a = [1,2,3]
a.inject(a) do |this, element|
  this == a #=> true
  this.include?(element) #=> true
  this
end

      

Aside from looking a little redundant, you should be sure to return at this

the end of each iteration, as the return value will become this

in the next iteration. For this reason (and the fact that you can just reference your collection in a block each

, as in David's answer), I don't recommend using that.


Edit - as Plain Lime pointed out in the comments - I missed the obvious one Enumerator#with_object

, which has the same (rather pointless) one but without the lack of backtracking this

at the end of each iteration. For example:

a = [1,2,3]
a.map.with_object(a) do |element, this|
  this == a #=> true, for each iteration
end

      

I still don't recommend using this.

0


source







All Articles