Как сослаться на переменную класса вне класса в файле модуля в Ruby - PullRequest
0 голосов
/ 13 апреля 2020

Я пытаюсь сослаться на переменную класса в классе в файле модуля:

require 'pry'
require_relative '../lib/concerns/memorable'

class Song
  extend Memorable::ClassMethods
  extend Findable::ClassMethods
  attr_accessor :name
  attr_reader :artist

  @@songs = []

  def initialize
    @@songs << self
  end

  # def self.find_by_name(name)
  #   @@songs.detect{|a| a.name == name}
  # end

  def self.all
    @@songs
  end

  # def self.reset_all
  #   self.all.clear
  # end
  #
  # def self.count
  #   self.all.count
  # end

  def artist=(artist)
    @artist = artist
  end

  def to_param
    name.downcase.gsub(' ', '-')
  end
end
module Findable
  module ClassMethods

    def all
      @@artists
    end

    def all
      @@songs
    end

    def find_by_name(name)
      @@songs.detect{|a| a.name == name}
    end

    def self.find_by_name(name)
      @@artists.detect{|a| a.name == name}
    end

 end

end

Ответы [ 2 ]

0 голосов
/ 13 апреля 2020

Распространенным способом реализации общего поведения является требование определенного интерфейса. Например, модуль Enumerable требует, чтобы вы внедрили each для работы большинства методов. (Некоторым методам, таким как sort, необходимы элементы внутри для реализации оператора <=>.)

Чтобы применить это к тому, что вы пытаетесь сделать, вам могут потребоваться классы, расширяющие модуль для реализации all метод. Вам не нужно проверять это специально. Просто предположим, что есть метод all, если пользователь не увидит исключение "NoMethodError: неопределенный метод" all "для Song: Class" , что довольно ясно.

module Findable
  ##
  # The class extending Findable::ClassMethods must provide a method
  # `all` which returns an Enumerable collection.
  module ClassMethods
    def find_by_name(name)
      all.select { |instance| instance.name == name }
    end
  end
end

class Song
  extend Findable::ClassMethods
  attr_accessor :name, :artist

  @@songs = []

  def initialize
    @@songs << self
  end

  def self.all
    @@songs
  end
end

foo = Song.new
foo.name = "foo"

bar = Song.new
bar.name = "bar"

Song.all
#=> [#<Song:0x0055828c8ca3e8 @name="foo">, #<Song:0x0055828c8cc9e0 @name="bar">]

Song.find_by_name("foo")
#=> [#<Song:0x0055828c8ca3e8 @name="foo">]
0 голосов
/ 13 апреля 2020

Проверить class_variable_get :

    module Findable
      module ClassMethods

        def all
          self.class_variable_get(:@@songs)
        end

        def find_by_name(name)
          self.class_variable_get(:@@songs).detect{|a| a.name == name}
        end

      end
    end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...