Могу ли я использовать метод суперкласса для установки переменной класса для своего подкласса в ruby? [Дубликат]

Я создал прототипный метод, который использует classList, если это возможно, и прибегает к indexOf:

Element.prototype.hasClass = Element.prototype.hasClass || 
  function(classArr){
    var hasClass = 0,
        className = this.getAttribute('class');
  
    if( this == null || !classArr || !className ) return false;
  
    if( !(classArr instanceof Array) )
      classArr = classArr.split(' ');

    for( var i in classArr )
      // this.classList.contains(classArr[i]) // for modern browsers
      if( className.split(classArr[i]).length > 1 )  
          hasClass++;

    return hasClass == classArr.length;
};


///////////////////////////////
// TESTS (see browser's console when inspecting the output)

var elm1 = document.querySelector('p');
var elm2 = document.querySelector('b');
var elm3 = elm1.firstChild; // textNode
var elm4 = document.querySelector('text'); // SVG text

console.log( elm1, ' has class "a": ', elm1.hasClass('a') );
console.log( elm1, ' has class "b": ', elm1.hasClass('b') );
console.log( elm1, ' has class "c": ', elm1.hasClass('c') );
console.log( elm1, ' has class "d": ', elm1.hasClass('d') );
console.log( elm1, ' has class "a c": ', elm1.hasClass('a c') );
console.log( elm1, ' has class "a d": ', elm1.hasClass('a d') );
console.log( elm1, ' has class "": ', elm1.hasClass('') );

console.log( elm2, ' has class "a": ', elm2.hasClass('a') );

// console.log( elm3, ' has class "a": ', elm3.hasClass('a') );

console.log( elm4, ' has class "a": ', elm4.hasClass('a') );

This is a test string

SVG Text Example

Страница тестирования

38
задан MPelletier 22 June 2012 в 03:11
поделиться

1 ответ

@@variables не являются переменными класса. Они являются переменными иерархии классов , то есть они распределяются между всей иерархией классов, включая все подклассы и все экземпляры всех подклассов. (Было высказано предположение, что нужно думать о @@variables больше как $$variables, потому что у них на самом деле больше общего с $globals, чем с @ivars. Таким образом, это меньше путаницы. Другие пошли дальше и предлагают, чтобы они должен быть просто удален с языка.)

Ruby не имеет переменных класса в том смысле, что, скажем, Java (там, где они называются статическими полями), имеет их. Это не переменные класса , потому что классы также являются объектами, поэтому они могут иметь переменные instance , как и любой другой объект. Все, что вам нужно сделать, это удалить посторонние @ s. (И вам нужно будет предоставить метод доступа для переменной экземпляра класса.)

class A
  def self.init config
    @config = config
  end

  def self.config # This is needed for access from outside
    @config
  end

  def config
    self.class.config # this calls the above accessor on self's class
  end
end

Давайте немного упростим это, так как A.config явно просто атрибут_reader:

class A
  class << self
    def init config
      @config = config
    end

    attr_reader :config
  end

  def config
    self.class.config
  end
end

И, на самом деле, A.init - просто писатель с забавным именем, поэтому переименуем его в A.config= и сделаем его автором, что, в свою очередь, означает, что наша пара методов теперь просто пара аксессуаров. (Так как мы изменили API, тестовый код также должен измениться, очевидно.)

class A
  class << self
    attr_accessor :config
  end

  def config
    self.class.config
  end
end

class B < A; end
class C < A; end

B.config = "bar"
p B.new.config  # => "bar"
p C.new.config  # => nil

C.config = "foo"
p B.new.config  # => "bar"
p C.new.config  # => "foo"

Однако я не могу поколебать ощущение, что в дизайне есть что-то более фундаментально, если вам это нужно вообще.

102
ответ дан Jörg W Mittag 23 August 2018 в 23:54
поделиться
Другие вопросы по тегам:

Похожие вопросы: