Refinements take place at block passing. [Feature #14223]
https://github.com/ruby/ruby/blob/v2_6_0/NEWS
It's very useful when you want to use the literals as DSL for the block.
Following example refines Integer#to_proc
and Array#to_proc
to slice the values.
using Module.new {
refine(Integer) do
def to_proc
-> o { o[self] }
end
end
refine(Array) do
def to_proc
# Same as -> o { map(&o.method(:[]) }
# https://dev.to/hanachin/ruby-27-new-feature-method-reference-operator-38l2
-> o { map(&o.:[]) }
end
end
}
p "foo".match(/(a)(b)(c)/)&.then(&1) #=> nil
p "abc".match(/(a)(b)(c)/)&.then(&1) #=> "a"
p "abc".match(/(a)(b)(c)/)&.then(&[1]) #=> ["a"]
p "abc".match(/(a)(b)(c)/)&.then(&[1,2,3]) #=> ["a","b","c"]
Top comments (5)
&o.:[]
the amount of sugar in these 6 symbols gave me diabetes.140% symbols😋🍭
map(&o.:[])
(
&
.
:
[
]
)
map{|k|o[k]}
{
|
[
]
}
I don't have a damn idea what I am looking at.
My guess is
&1
is1.to_proc()
ando
is the receiver object (e.g.a.map(&0)
would doa.map( -> a[0])
) and the sugar diabetes thingy isa.[].to_proc()
. If I'm wrong please correct me @hanachin .There's something similar in Kotlin though I like their implementation more.
That's correct!
&
would implicitly call#to_proc
to convert the object to Proc object.But before 2.6,
#to_proc
that defined in Refinements are ignored at&
operator.In 2.6, we can use
#to_proc
for&
operator.