Development Tip

인스턴스화 된 개체에 메서드 추가

yourdevel 2021. 1. 5. 19:39
반응형

인스턴스화 된 개체에 메서드 추가


obj = SomeObject.new

def obj.new_method
  "do some things"
end

puts obj.new_method
> "do some things"

이것은 잘 작동합니다. 그러나 기존 메서드 내에서 동일한 작업을 수행해야합니다.

def some_random_method
  def obj.new_method
    "do some things"
  end
end

잘 작동하지만 메서드 내부에 메서드가 있으면 꽤 끔찍해 보입니다. 문제는 그러한 방법을 추가하는 다른 방법이 있습니까?


내가 이것을 물은 지 오래되었습니다. 루비 1.9 이상에서는 define_singleton_method다음과 같이 를 사용하여 더 좋은 방법이 있습니다.

obj = SomeObject.new

obj.define_singleton_method(:new_method) do
  "do some things"
end

Mixin을 사용하십시오.

module AdditionalMethods
  def new_method
    "do some things"
  end
end

obj = SomeObject.new
obj.extend(AdditionalMethods)

puts obj.new_method
> "do some things"

주목할 흥미로운 점 :

대신 간 경우 :

def my_method
    def my_other_method; end
end

그런 다음 my_other_method실제로 수신자 my_method가 인스턴스 라는 사실에도 불구하고 객체의 CLASS에 정의됩니다 .

그러나 당신이 가면 (당신이했던 것처럼) :

def my_method
    def self.my_other_method; end
end

그런 다음 my_other_method인스턴스의 고유 클래스에 정의됩니다.

귀하의 질문과 직접 ​​관련이 없지만 그럼에도 불구하고 흥미 롭습니다.)


모듈을 사용할 수 있습니다.

module ObjSingletonMethods
  def new_method
    "do some things"
  end
end


obj.extend ObjSingletonMethods

puts obj.new_method # => do some things

이제 해당 객체에 더 많은 메서드를 추가해야하는 경우 모듈에서 메서드를 구현하기 만하면됩니다.


이를 달성하는 방법에는 여러 가지가 있으며 모두 싱글 톤 클래스와 관련이 있습니다.

  1. class <<관용구를 사용하여 싱글 톤 클래스 정의를 열 수 있습니다 .

    obj = Object.new
    class << obj
      def my_new_method
         ...
      end
    end
    
  2. 또는 define_singleton_methodobj에서 사용할 수 있습니다 .

    obj = Object.new
    obj.define_sigleton_method(:my_new_method) do
         ...
    end
    
  3. define_method싱글 톤 클래스에서 사용할 수도 있습니다 .

    obj = Object.new
    obj.singleton_class.define_method(:my_new_method) do
         ...
    end
    
  4. 또는 def직접 사용할 수 있습니다.

    obj = Object.new
    def obj.my_new_method
         ...
    end
    

예제 3에 주목하세요. 싱글 톤 클래스의 개념이 더 명확 해집니다. 이 두 가지 예에는 차이가 있습니다.

    a = Object.new
    b = Object.new

    # -- defining a new method in the object's "class" --
    a.class.define_method(:abc) do
      puts "hello abc"
    end

    a.abc # prints "hello abc"
    b.abc # also prints "hello abc"

    # -- defining a new method in the object's "singleton class" --
    a.singleton_class.define_method(:bcd) do
      puts "hello bcd"
    end

    a.bcd # prints "hello bcd"
    b.bcd # error undefined method

모든 객체에는 고유 한 싱글 톤 클래스가 있기 때문입니다.

    a = Object.new
    b = Object.new

    p a.class # prints "Object"
    p a.singleton_class # prints "#<Class:#<Object:0x000055ebc0b84438>>"

    p b.class # also prints "Object"
    p b.singleton_class # prints "#<Class:#<Object:0x000055ebc0b84410>>" (a different reference address)

사용 instance_eval:

obj = SomeObject.new

obj.instance_eval do
  def new_method
    puts 'do something new'
  end
end

obj.new_method 
> "do something new"

class Some
end 

obj = Some.new

class << obj
  def hello 
    puts 'hello'
  end 
end 

obj.hello

obj2 = Some.new
obj2.hello # error

구문 class << obj은 객체에 대한 클래스 정의를 여는 것을 의미합니다. 아시다시피 다음과 같은 구문을 사용하여 Ruby 클래스 메서드를 정의 할 수 있습니다.

class Math

    class << self 

        def cos(x)
            ...
        end 

        def sin(x)
            ...
        end 
    end 
end 

Then we can use those methods like this:

Math.cos(1)

In Ruby, everything is an object - even classes. self here is an object of Math class itself (you can access that object with Math.class). So syntax class << self means we are opening class for Math class object. Yes, it means that Math class has class too (Math.class.class).

ReferenceURL : https://stackoverflow.com/questions/1887845/add-method-to-an-instanced-object

반응형