Pergunta

O que class << self fazer em rubi?

Foi útil?

Solução

Primeiro, o class << foo A sintaxe é aberta fooClasse de Singleton de Singleton (EigEnclass). Isso permite que você especialize o comportamento dos métodos chamados nesse objeto específico.

a = 'foo'
class << a
  def inspect
    '"bar"'
  end
end
a.inspect   # => "bar"

a = 'foo'   # new object, new singleton class
a.inspect   # => "foo"

Agora, para responder à pergunta: class << self abre selfa classe singleton, para que os métodos possam ser redefinidos para a corrente self objeto (que dentro de uma classe ou corpo de módulo é a classe ou módulo em si). Geralmente, isso é usado para definir métodos de classe/módulo ("estático"):

class String
  class << self
    def value_of obj
      obj.to_s
    end
  end
end

String.value_of 42   # => "42"

Isso também pode ser escrito como uma abreviação:

class String
  def self.value_of obj
    obj.to_s
  end
end

Ou ainda mais curto:

def String.value_of obj
  obj.to_s
end

Quando dentro de uma definição de função, self refere -se ao objeto em que a função está sendo chamada. Nesse caso, class << self abre a classe Singleton para esse objeto; Um uso disso é implementar a máquina de estado de um homem pobre:

class StateMachineExample
  def process obj
    process_hook obj
  end

private
  def process_state_1 obj
    # ...
    class << self
      alias process_hook process_state_2
    end
  end

  def process_state_2 obj
    # ...
    class << self
      alias process_hook process_state_1
    end
  end

  # Set up initial state
  alias process_hook process_state_1
end

Então, no exemplo acima, cada instância de StateMachineExample tem process_hook aliases para process_state_1, mas observe como neste último, pode redefinir process_hook (por self apenas, não afetando outro StateMachineExample instâncias) para process_state_2. Então, cada vez que um chamador liga para o process Método (que chama o redefinível process_hook), o comportamento muda dependendo do estado em que está.

Outras dicas

Eu encontrei uma explicação super simples sobre class << self , Eigenclass e tipo diferente de methods nisso blog.

Em Ruby, existem três tipos de métodos que podem ser aplicados a uma classe:

  1. Métodos de instância
  2. Métodos Singleton
  3. Métodos de classe

Os métodos de instância e os métodos de classe são quase semelhantes ao seu homônimo em outras linguagens de programação.

class Foo  
  def an_instance_method  
    puts "I am an instance method"  
  end  
  def self.a_class_method  
    puts "I am a class method"  
  end  
end

foo = Foo.new

def foo.a_singleton_method
  puts "I am a singletone method"
end

Outra maneira de acessar um Eigenclass(que inclui métodos singleton) é com a seguinte sintaxe (class <<):

foo = Foo.new

class << foo
  def a_singleton_method
    puts "I am a singleton method"
  end
end

Agora você pode definir um método singleton para self qual é a classe Foo próprio neste contexto:

class Foo
  class << self
    def a_singleton_and_class_method
      puts "I am a singleton method for self and a class method for Foo"
    end
  end
end

Geralmente, os métodos de instância são métodos globais. Isso significa que eles estão disponíveis em todos os casos da classe em que foram definidos. Por outro lado, um método singleton é implementado em um único objeto.

O Ruby armazena métodos nas classes e todos os métodos devem estar associados a uma classe. O objeto no qual um método singleton é definido não é uma classe (é uma instância de uma classe). Se apenas as aulas podem armazenar métodos, como um objeto pode armazenar um método singleton? Quando um método Singleton é criado, Ruby cria automaticamente uma classe anônima para armazenar esse método. Essas classes anônimas são chamadas metaclasses, também conhecidas como aulas de singleton ou eigenclasses. O método Singleton está associado ao metaclasse que, por sua vez, está associado ao objeto no qual o método singleton foi definido.

Se vários métodos de singleton forem definidos em um único objeto, todos serão armazenados no mesmo metaclasse.

class Zen
end

z1 = Zen.new
z2 = Zen.new

class << z1
  def say_hello
    puts "Hello!"
  end
end

z1.say_hello    # Output: Hello!
z2.say_hello    # Output: NoMethodError: undefined method `say_hello'…

No exemplo acima, a classe << Z1 altera o eu atual para apontar para a metaclasse do objeto Z1; Em seguida, define o método SAY_HELLO dentro da metaclasse.

As classes também são objetos (instâncias da classe interna chamada Class). Os métodos de classe nada mais são do que métodos de singleton associados a um objeto de classe.

class Zabuton
  class << self
    def stuff
      puts "Stuffing zabuton…"
    end
  end
end

Todos os objetos podem ter metaclasses. Isso significa que as aulas também podem ter metaclasses. No exemplo acima, a classe << se modifica, para que aponte para a metaclasse da classe Zabuton. Quando um método é definido sem um receptor explícito (a classe/objeto em que o método será definido), ele é implicitamente definido no escopo atual, ou seja, o valor atual do eu. Portanto, o método do material é definido dentro da metaclasse da classe Zabuton. O exemplo acima é apenas outra maneira de definir um método de classe. IMHO, é melhor usar a sintaxe def O exemplo acima foi incluído, para que entendamos o que está acontecendo quando encontramos a classe << sintaxe self.

Informações adicionais podem ser encontradas em Este post sobre aulas de rubi.

Que classe << Coisa:

class Hi
  self #=> Hi
  class << self #same as 'class << Hi'
    self #=> #<Class:Hi>
    self == Hi.singleton_class #=> true
  end
end

faz self == thing.singleton_class no contexto de seu bloco.


O que é coisa.singleton_class?

hi = String.new
def hi.a
end

hi.class.instance_methods.include? :a #=> false
hi.singleton_class.instance_methods.include? :a #=> true

hi Objeto herda seu #methods de seu #singleton_class.instance_methods e então de seu #class.instance_methods.
Aqui demos hi's Classe Singleton método de instância :a. Poderia ter sido feito com classe << oi em vez de.
hi's #singleton_class tem todos os métodos de instância hi's #class tem, e possivelmente mais um pouco (:a aqui).

Métodos de instância de coisa #class e #singleton_class pode ser aplicado diretamente à coisa. Quando Ruby vê a coisa.


A propósito - eles chamam de objeto Classe Singleton == metaclasse == Eigenclass.

A. Método Singleton é um método definido apenas para um único objeto.

Exemplo:

class SomeClass
  class << self
    def test
    end
  end
end

test_obj = SomeClass.new

def test_obj.test_2
end

class << test_obj
  def test_3
  end
end

puts "Singleton's methods of SomeClass"
puts SomeClass.singleton_methods
puts '------------------------------------------'
puts "Singleton's methods of test_obj"
puts test_obj.singleton_methods

Métodos de Someclass de Singleton

teste


Métodos de Singleton de test_obj

test_2

test_3

De fato, se você escrever alguma extensão C para seus projetos de rubi, existe realmente apenas uma maneira de definir um método de módulo.

rb_define_singleton_method

Sei que esse auto -negócio abre todos os tipos de outras perguntas para que você possa fazer melhor pesquisando cada parte.

Objetos primeiro.

foo = Object.new

Posso fazer um método para foo?

Claro

def foo.hello
 'hello'
end

O que eu faço com isso?

foo.hello
 ==>"hello"

Apenas outro objeto.

foo.methods

Você obtém todos os métodos de objeto mais o seu novo.

def foo.self
 self
end

foo.self

Apenas o objeto foo.

Tente ver o que acontece se você fizer foo de outros objetos, como classe e módulo. Os exemplos de todas as respostas são bons de brincar, mas você precisa trabalhar com idéias ou conceitos diferentes para realmente entender o que está acontecendo com a maneira como o código é escrito. Então agora você tem muitos termos para procurar.

Singleton, Classe, Module, Self, Objeto e Eigenclass foram criados, mas Ruby não nomeia modelos de objetos dessa maneira. É mais como Metaclass. Richard ou __lha que mostra a ideia aqui.http://viewsourcecode.org/why/hacking/seeingmetaclassclearly.htmlE se o derrubar, tente procurar um modelo de objeto Ruby na pesquisa. Dois vídeos que eu conheço no YouTube são Dave Thomas e Peter Cooper. Eles tentam explicar esse conceito também. Dave levou muito tempo para obtê -lo, então não se preocupe. Ainda estou trabalhando nisso também. Por que mais eu estaria aqui? Obrigado pela sua pergunta. Dê uma olhada também na biblioteca padrão. Possui um módulo singleton como um FYI.

Isso é muito bom.https://www.youtube.com/watch?v=i4uiywa8efk

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top