سؤال

class << self
attr_accessor :n, :totalX, :totalY
end

يستخدم بناء الجملة أعلاه لتحديد متغيرات مثيل الطبقة. ولكن عندما أفكر في ما يعنيه بناء الجملة، فإنه لا معنى لي، لذلك أتساءل إذا تم استخدام هذا النوع من بناء الجملة لأي أنواع أخرى من التعاريف. وجهة نظري من الارتباك هنا هذا:

class << self

يعني عامل إلحاق التطبيق عادة "إضافة ما هو على الحق في الكائن على اليسار". ولكن في سياق هذه الكتلة، كيف تضيف ذلك إلى "وضع محتويات هذه الكتلة في تعريف مثيل الفصل بدلا من المثيل"؟

للسبب نفسه في حيرة من أمري لماذا في فئة سياق واحدة << يمكن أن تحدد الذات لمتغيرات مثيل الفصل أثناء وجودها في حالة أخرى، يبدو أنها تخلق متغيرات فئة مثل هنا:

class Point
  # Instance methods go here
  class << self
    # Class methods go here
  end
end
هل كانت مفيدة؟

المحلول

في Ruby، يمكنك إعادة فتح الفئات الحالية وإضافة طرق. وهذا هو، يمكنك أن تقول:

class Foo
  def bob
    return "hello from bob"
  end
end

يتم تخزين هذه الأساليب في مكان ما في قاموس داخلي (ربما متغير مثيل) من Foo-Class (وهو مجرد مثيل ClassClass وبالتالي لديها متغيرات سريعة)

لكن الشيء المقسوم هو أنه يمكنك أيضا إضافة طرق إلى الحالات الكائنات الحالية

foo = Foo.new
foo2 = Foo.new

def foo.fred
  return "I am fred"
end


foo.fred  #=> "I am fred"
foo2.fred #=> NoMethodError

لكن أين هذه الطريقة مخزنة بالفعل?

اتضح أن روبي يخلق فئة جديدة وراء الكواليس (تسمى أحيانا فئة Singleton, metaclass. أو eigenclass.) التي يتم إدراجها في وراثة الميراث ما بين ال Fooتشرس ومثالته.

لذلك فإن علاقة الميراث تبدو وكأنها:

foo < (eigenclass of foo) < Foo < Class

(إذا قلت foo.superclass فلن ترى فئة Singleton)

ال class << X-Syntax هو وسيلة للوصول إلى هذه الطبقة الخاصة، حتى تتمكن من التعامل معها مباشرة. كتل التعليمات البرمجية التالية تعادل بالضبط:

def foo.bar
  return "xy"
end

# is exactly the same as

class << foo
  def bar
    return "xy"
  end
end

لذلك التشابه بين class Foo < Bar و class << Foo ليس عرضي، هناك ميراث يحدث في كليهما.

افكر في class << X كما "فتح metaclass من x"

الشيء الذي يجب تذكره في روبي هو أن الطبقات نفسها هي مجرد كائنات. (مثيلات الفصل Class) لذلك إذا قلت:

class Foo
  class << self
    def k
      return "x"
    end
  end
end

(self لا بد أن Foo في كتلة الرمز هذا) k هو طريقة المثال من eigenclass Foo, ، مما يجعلها طريقة الفصل Foo

كل هذا هو أكثر وضوحا في الفصل عن فصول من Pickaxe (إصدار الويب لا يحتوي على المخططات، لسوء الحظ) و _whys رؤية metaclasses بوضوح

نصائح أخرى

فكر في الفصل على أنه يحتوي على قاموس أعضاء بما في ذلك جميع متغيرات الملالات والمثيل. عندما تخبر الفصل إلى "إلحاق" ب "نفسه"، فأنت تقول "أضف هذه إلى قاموس أعضاء الفصل".

سوف يمنح التدوين هو هنكي قليلا، رغم ذلك.

انها في الواقع مربكة للتفكير في الأمر من حيث مشغل "إلحاق". طريقة أفضل للنظر في ذلك هو أنه class Foo يفتح FOO Class، أي أنه يحدد "الذات" إلى كائن فئة فو، مما يخلقه إذا لزم الأمر، لذلك class << self يفتح Eigenclass من كائن "الذات" الحالي. لاحظ أنه لا يقتصر على الذات - أي شريط كائن، يمكنك أن تقول الفئة << شريط لفتح eigenclass من هذا الكائن.

class A
  def hello
    print "hello world"
  end
end

a = A.new
b = A.new

class << a
  def goodbye
    print "goodbye cruel world"
  end
end

a.hello
b.hello
a.goodbye
b.goodbye
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top