[ruby] 루비 : 자기 확장

Ruby에서는 extend. 그러나이 코드 세그먼트에서 무슨 일이 일어나고 있습니까? 구체적으로 무엇을 extend합니까? 인스턴스 메서드를 클래스 메서드로 만드는 편리한 방법입니까? 처음부터 클래스 메서드를 지정하는 대신 왜 이런 방식으로 수행합니까?

module Rake
  include Test::Unit::Assertions

  def run_tests # etc.
  end

  # what does the next line do?
  extend self
end



답변

인스턴스 메서드를 클래스 메서드로 만드는 편리한 방법입니다. 그러나 더 효율적인 싱글 톤 으로 사용할 수도 있습니다 .


답변

모듈에서 self는 모듈 클래스 자체입니다. 예를 들어

puts self

Rake를 반환합니다.

extend self

기본적으로 Rake에 정의 된 인스턴스 메소드를 사용할 수 있도록합니다.

Rake.run_tests


답변

나를 위해 항상 생각하는 데 도움이 extend같은 include싱글 톤 클래스 (또한 메타 또는 고유 클래스라고도 함) 내부.

싱글 톤 클래스 내에 정의 된 메서드는 기본적으로 클래스 메서드라는 것을 알고있을 것입니다.

module A
  class << self
    def x
      puts 'x'
    end
  end
end

A.x #=> 'x'

이제 우리는 알고 있다는 extendinclude, 따라서 단일 클래스 내부와 모듈의 방법은 클래스 메소드로 노출 :

module A
  class << self
    include A

    def x
      puts 'x'
    end
  end

  def y
    puts 'y'
  end
end

A.x #=> 'x'
A.y #=> 'y'


답변

링크 부패를 방지하기 위해 user83510이 링크 한 Chris Wanstrath블로그 게시물이 아래에 다시 게시됩니다 (그의 허락하에). 그래도 원본을 능가하는 것은 없으므로 계속 작동하는 한 그의 링크를 사용하십시오.


→ singin ‘singletons 2008 년 11 월 18 일 내가 이해하지 못하는 것이 있습니다. 예를 들어 데이비드 보위. 또는 남반구. 그러나 Ruby의 Singleton만큼 내 마음을 흔들리는 것은 없습니다. 정말로, 그것은 완전히 불필요하기 때문입니다.

다음은 코드로 사용자가 원하는 작업입니다.

require 'net/http'

# first you setup your singleton
class Cheat
  include Singleton

  def initialize
    @host = 'http://cheat.errtheblog.com/'
    @http = Net::HTTP.start(URI.parse(@host).host)
  end


  def sheet(name)
    @http.get("/s/#{name}").body
  end
end

# then you use it
Cheat.instance.sheet 'migrations'
Cheat.instance.sheet 'yahoo_ceo'

그러나 그것은 미친 짓입니다. 힘과 싸워라.

require 'net/http'

# here's how we roll
module Cheat
  extend self

  def host
    @host ||= 'http://cheat.errtheblog.com/'
  end

  def http
    @http ||= Net::HTTP.start(URI.parse(host).host)
  end

  def sheet(name)
    http.get("/s/#{name}").body
  end
end

# then you use it
Cheat.sheet 'migrations'
Cheat.sheet 'singletons'

왜 안돼? API는 더 간결하고 코드는 테스트, 모의, 스텁이 더 쉬우 며 필요에 따라 적절한 클래스로 변환하는 것은 여전히 ​​간단합니다.

((저작권 ought ten chris wanstrath))


답변

extend self기존의 모든 인스턴스 메서드를 모듈 메서드로 포함합니다. 이것은 말하는 것과 같습니다 extend Rake. 또한 Rakeclass의 객체입니다 Module.

동등한 동작을 달성하는 또 다른 방법은 다음과 같습니다.

module Rake
  include Test::Unit::Assertions

  def run_tests # etc.
  end

end

Rake.extend(Rake)

이것은 private 메서드로 자체 포함 된 모듈을 정의하는 데 사용할 수 있습니다.


답변