Computer >> 컴퓨터 >  >> 프로그램 작성 >> Ruby

`items.map(&:name)`이 작동하도록 하는 영리한 해킹

배열을 반복할 때 계속해서 사용하는 속기 한 가지가 있습니다. "앰퍼샌드 콜론" 또는 "프레첼 콜론"이라고도 하는 &:트릭입니다. 익숙하지 않은 경우 작동 방식은 다음과 같습니다.

words = ["would", "you", "like", "to", "play", "a", "game?"]

# this...
words.map &:length

# ..is equivalent to this:
words.map { |w| w.length }

최근까지 나는 &:구문이 연산자라고 가정했습니다. 하지만 그렇지 않습니다. ActiveSupport에서 시작하여 Ruby 1.8.7의 공식 기능이 된 영리한 해킹입니다.

&연산자

AND 논리 연산에 사용되는 것 외에도 "&" 문자는 Ruby에서 또 다른 용도로 사용됩니다. 메서드 인수의 시작 부분에 추가되면 피연산자에서 to_proc을 호출하고 블록으로 전달합니다. 한 입입니다. 예를 보는 것이 훨씬 간단합니다.

def my_method(&block)
  block.call
end

class Greeter
  def self.to_proc
    Proc.new { "hello" }
  end
end

my_method(&Greeter) # returns "hello"

심볼#to_proc

to_proc를 추가할 수 있습니다. Symbol을 포함한 모든 객체에 대한 메서드. 이것이 바로 ruby가 &: 지름길. 다음과 같이 보입니다.

class Symbol
  def to_proc
    Proc.new do |item|
      item.send self
    end
  end
end

진흙처럼 맑은? 중요한 부분은 item.send(self)입니다. . Self는 이 경우 기호를 나타냅니다.

모두 합치기

each와 같은 번호를 매길 수 있는 메서드 및 map 블록을 수락합니다. 각 항목에 대해 블록을 호출하고 항목에 대한 참조를 전달합니다. 이 경우 블록은 기호에서 to_proc을 호출하여 생성됩니다.

# &:name evaluates to a Proc, which does item.send(:name)
items.map(&:name)

여기서 흥미로운 점은 map 무슨 일이 일어나고 있는지  알 수 없습니다! 대부분의 작업은 :name에 의해 수행됩니다. 상징. 그것은 확실히 영리합니다 ... 내 취향에 거의 너무 영리합니다. 그러나 이 시점에서 수년 동안 Ruby 표준 라이브러리의 일부였으며 너무 편리해서 당장은 사용을 중단할 것 같습니다. :)