programing

Ruby: 인스턴스의 호출 클래스 메서드

yellowcard 2023. 6. 4. 10:24
반응형

Ruby: 인스턴스의 호출 클래스 메서드

루비에서 해당 클래스의 인스턴스 중 하나에서 클래스 메소드를 어떻게 부르나요?있다고 해요

class Truck
  def self.default_make
    # Class method.
    "mac"
  end

  def initialize
    # Instance method.
    Truck.default_make  # gets the default via the class's method.
    # But: I wish to avoid mentioning Truck. Seems I'm repeating myself.
  end
end

전선Truck.default_make기본값을 검색합니다.하지만 언급하지 않고 이 말을 할 수 있는 방법이 있습니까?Truck있어야 할 것 같습니다.

클래스의 문자 그대로의 이름을 참조하는 대신 인스턴스 메서드 내에서 호출할 수 있습니다.self.class.whatever.

class Foo
    def self.some_class_method
        puts self
    end

    def some_instance_method
        self.class.some_class_method
    end
end

print "Class method: "
Foo.some_class_method

print "Instance method: "
Foo.new.some_instance_method

출력:

클래스 방법:인스턴스 메서드:

사용.self.class.blah사용하는 것과 같지 않습니다.ClassName.blah상속에 관해서는

class Truck
  def self.default_make
    "mac"
  end

  def make1
    self.class.default_make
  end

  def make2
    Truck.default_make
  end
end


class BigTruck < Truck
  def self.default_make
    "bigmac"
  end
end

ruby-1.9.3-p0 :021 > b=BigTruck.new
 => #<BigTruck:0x0000000307f348> 
ruby-1.9.3-p0 :022 > b.make1
 => "bigmac" 
ruby-1.9.3-p0 :023 > b.make2
 => "mac" 

인스턴스 메서드 내의 클래스 메서드에 액세스하려면 다음을 수행합니다.

self.class.default_make

다음은 문제를 해결할 수 있는 대안입니다.

class Truck

  attr_accessor :make, :year

  def self.default_make
    "Toyota"
  end

  def make
    @make || self.class.default_make
  end

  def initialize(make=nil, year=nil)
    self.year, self.make = year, make
  end
end

이제 클래스를 사용해 보겠습니다.

t = Truck.new("Honda", 2000)
t.make
# => "Honda"
t.year
# => "2000"

t = Truck.new
t.make
# => "Toyota"
t.year
# => nil

위임 방법에 액세스할 수 있는 경우 다음 작업을 수행할 수 있습니다.

[20] pry(main)> class Foo
[20] pry(main)*   def self.bar
[20] pry(main)*     "foo bar"
[20] pry(main)*   end  
[20] pry(main)*   delegate :bar, to: 'self.class'
[20] pry(main)* end  
=> [:bar]
[21] pry(main)> Foo.new.bar
=> "foo bar"
[22] pry(main)> Foo.bar
=> "foo bar"

또는 클래스 및 인스턴스에 위임할 메서드가 한두 개 이상 있는 경우에는 더 깨끗해질 수 있습니다.

[1] pry(main)> class Foo
[1] pry(main)*   module AvailableToClassAndInstance
[1] pry(main)*     def bar
[1] pry(main)*       "foo bar"
[1] pry(main)*     end  
[1] pry(main)*   end  
[1] pry(main)*   include AvailableToClassAndInstance
[1] pry(main)*   extend AvailableToClassAndInstance
[1] pry(main)* end  
=> Foo
[2] pry(main)> Foo.new.bar
=> "foo bar"
[3] pry(main)> Foo.bar
=> "foo bar"

주의 사항:

아무렇게나 하지 마delegate이상한 이름 충돌 문제가 발생하기 시작하기 때문에 상태가 클래스 및 인스턴스로 변경되지 않는 모든 것.이 작업을 적게 수행하고 확인한 후에만 다른 작업이 취소됩니다.

self.class.default_make

당신은 옳은 방법으로 그것을 하고 있습니다.클래스 메소드(C++ 또는 Java의 'static' 메소드와 유사)는 인스턴스의 일부가 아니므로 직접 참조해야 합니다.

따라서 예제에서는 'default_make'를 정규 메서드로 사용하는 것이 좋습니다.

#!/usr/bin/ruby

class Truck
    def default_make
        # Class method.
        "mac"
    end

    def initialize
        # Instance method.
        puts default_make  # gets the default via the class's method.
    end
end

myTruck = Truck.new()

클래스 메소드는 클래스를 사용하는 유틸리티 유형 함수에 더 유용합니다.예:

#!/usr/bin/ruby

class Truck
    attr_accessor :make

    def default_make
        # Class method.
        "mac"
    end

    def self.buildTrucks(make, count)
        truckArray = []

        (1..count).each do
            truckArray << Truck.new(make)
        end

        return truckArray
    end

    def initialize(make = nil)
        if( make == nil )
            @make = default_make()
        else
            @make = make
        end
    end
end

myTrucks = Truck.buildTrucks("Yotota", 4)

myTrucks.each do |truck|
    puts truck.make
end

하나 더:

class Truck
  def self.default_make
    "mac"
  end

  attr_reader :make

  private define_method :default_make, &method(:default_make)

  def initialize(make = default_make)
    @make = make
  end
end

puts Truck.new.make # => mac

다음은 고객이 다음을 구현하는 방법에 대한 접근 방식입니다._class로 작동하는 방법self.class이런 상황에서참고: 생산 코드에서는 사용하지 마십시오. 이익을 위한 것입니다. :)

보낸 사람: 루비에서 호출자의 컨텍스트에서 코드를 평가할 수 있습니까? 또한 http://rubychallenger.blogspot.com.au/2011/07/caller-binding.html .

# Rabid monkey-patch for Object
require 'continuation' if RUBY_VERSION >= '1.9.0'
class Object
  def __; eval 'self.class', caller_binding; end
  alias :_class :__
  def caller_binding
    cc = nil; count = 0
    set_trace_func lambda { |event, file, lineno, id, binding, klass|
      if count == 2
        set_trace_func nil
        cc.call binding
      elsif event == "return"
        count += 1
      end
    }
    return callcc { |cont| cc = cont }
  end
end

# Now we have awesome
def Tiger
  def roar
    # self.class.roar
    __.roar
    # or, even
    _class.roar
  end
  def self.roar
    # TODO: tigerness
  end
end

아마도 정답은 루비를 위한 패치를 제출하는 것입니다 :)

질문과 유사하게 다음을 사용할 수 있습니다.

class Truck
  def default_make
    # Do something
  end

  def initialize
    super
    self.default_make
  end
end

언급URL : https://stackoverflow.com/questions/2527830/ruby-calling-class-method-from-instance

반응형