আইজেনচ্লাসটি কেন স্বতঃবর্গের সমতুল্য নয়, যখন এটি দেখতে খুব সমান দেখাচ্ছে?


84

আমি কোথাও মেমো মিস করেছি এবং আমি আশা করি আপনি এটি আমার কাছে ব্যাখ্যা করবেন।

কেন কোনও বস্তুর আইজেনগ্লাস আলাদা self.class?

class Foo
  def initialize(symbol)
    eigenclass = class << self
      self
    end
    eigenclass.class_eval do
      attr_accessor symbol
    end
  end
end

আমার যুক্তির ট্রেন যা ইজেনক্লাসের সাথে সমান হয় class.selfতা বরং সহজ:

class << selfক্লাসের পদ্ধতিগুলি ঘোষণার উপায়, উদাহরণের পদ্ধতিগুলির চেয়ে। এটি একটি শর্টকাট def Foo.bar

সুতরাং শ্রেণি অবজেক্টের রেফারেন্সের মধ্যে, ফিরে আসা selfএকই রকম হওয়া উচিত self.class। এটি কারণ শ্রেণি পদ্ধতি / বৈশিষ্ট্যগুলির সংজ্ঞা class << selfনির্ধারণ selfকরা হবে Foo.class

আমি কি শুধু বিভ্রান্ত? বা, এটি কি রুবি মেটা-প্রোগ্রামিংয়ের একটি লুক্কায়িত কৌশল?

উত্তর:


123

class << selfক্লাসের পদ্ধতিগুলি ঘোষণা করার উপায় ছাড়াও এটি (যদিও এটি সেভাবে ব্যবহার করা যেতে পারে)। সম্ভবত আপনি কিছু ব্যবহার দেখেছেন:

class Foo
  class << self
    def a
      print "I could also have been defined as def Foo.a."
    end
  end
end

এটি কাজ করে, এবং এর সমতুল্য def Foo.a, তবে এটি যেভাবে কাজ করে তা সামান্য সূক্ষ্ম। রহস্যটি হ'ল self, সেই প্রসঙ্গে, সেই বস্তুকে বোঝায় Foo, যার শ্রেণি একটি অনন্য, বেনাম সাবক্লাস Class। এই সাবক্লাসকে বলা হয় Foo' আইজেনক্লাস ' । তাই def aনতুন পদ্ধতি নামক সৃষ্টি aমধ্যে Foo, স্বাভাবিক পদ্ধতি কল সিনট্যাক্স দ্বারা অ্যাক্সেসযোগ্য এর eigenclass: Foo.a

এখন অন্য একটি উদাহরণ তাকান:

str = "abc"
other_str = "def"

class << str
  def frob
    return self + "d"
  end
end

print str.frob # => "abcd"
print other_str.frob # => raises an exception, 'frob' is not defined on other_str

এই উদাহরণটি সর্বশেষের মতোই, যদিও প্রথমে বলা শক্ত হতে পারে। frobসংজ্ঞায়িত করা হয়, Stringক্লাসে নয়, এর আইজেনচ্লাসে str, একটি অনন্য বেনামে সাবক্লাস String। সুতরাং strএকটি frobপদ্ধতি আছে, কিন্তু উদাহরণস্বরূপ Stringনা। আমাদের কাছে স্ট্রিংয়ের ওভাররাইড পদ্ধতিগুলিও থাকতে পারে (কিছু নির্দিষ্ট টেস্টিং পরিস্থিতিতে খুব দরকারী)।

এখন আমরা আপনার আসল উদাহরণটি বোঝার জন্য সজ্জিত। ইনসাইড Foo'র আরম্ভ পদ্ধতি, selfক্লাসে না বোঝায় Foo, কিন্তু কিছু বিশেষ করার উদাহরণ হিসেবে বলা যায় এর Foo। এর আইজেনচ্লাসটি একটি সাবক্লাস Foo, তবে এটি নয় Foo; এটি হতে পারে না, নাহলে দ্বিতীয় কৌশলটিতে আমরা যে কৌশলটি দেখেছি তা কাজ করতে পারে না। সুতরাং আপনার উদাহরণ চালিয়ে যেতে:

f1 = Foo.new(:weasels)
f2 = Foo.new(:monkeys)

f1.weasels = 4 # Fine
f2.monkeys = 5 # Also ok
print(f1.monkeys) # Doesn't work, f1 doesn't have a 'monkeys' method.

আশাকরি এটা সাহায্য করবে.


তাহলে, প্রতিটি উদাহরণ তৈরি করা শ্রেণীর একটি বেনামে সাবক্লাস?
রবার্ট কে

21
প্রতিটি উদাহরণের ক্লাসটি তৈরি শ্রেণীর একটি বেনামে সাবক্লাস। f1 এর ক্লাসটি ফু এর বেনামে সাবক্লাস, ফু এর ক্লাস ক্লাসের একটি বেনামী সাবক্লাস।
ডেভিড সেলার

6
সুন্দর উত্তর :) অনেক লোক এটিকে আপনার মত পরিষ্কার বোঝে না।
অশ্বারোগ্য

4
এফ 1 এর আইজেনগ্লাস কীভাবে আলাদা হয়, ধারণাগতভাবে, F1 এর আসল উদাহরণ থেকে। যদি f1 হ'ল একমাত্র উদাহরণ যা এর আইজেনচ্লাসের পদ্ধতিগুলিতে অ্যাক্সেস পাবে, তবে F1 এবং এর আইজেনগ্লাসটি ভেঙে যাওয়ার মধ্যে পার্থক্য নেই?
এলজু

4
@ ইলজু হ্যাঁ, কিন্ডা সত্যই গুরুত্বপূর্ণ পার্থক্যটি "ফু" এবং "এফ 1 এর আইজেনক্লাস" এর মধ্যে রয়েছে; যদি আপনি এটি পেয়ে থাকেন, আপনি সম্ভবত ভাল আছেন।
ডেভিড সেলার

48

সহজ উত্তর: আইজেনক্লাসটি তাত্ক্ষণিকভাবে চালু করা যায় না।

class F
 def eigen
  class << self 
   self
  end
 end
end
F.new.eigen.new #=> TypeError: can't create instance of virtual class

এই ওয়েবসাইটে আপনার কেবলমাত্র 1 পয়েন্ট থাকতে পারে তবে আমি আপনাকে এবং আপনার স্টাইলটি পছন্দ করি।
ঘোড়াগুই 19

ডাব্লু / ব্যানস্টার সম্মত; এটি একটি দুর্দান্ত উত্তর
ক্রিস্টোফার স্কট

4
এটি একটি অত্যন্ত অন্তর্দৃষ্টিপূর্ণ এবং সহায়ক মন্তব্য যা আইএফএফ ইতিমধ্যে উপরে @ ডেভিডসিলারের উত্তরটি পড়েছে।
জাজ

থিও শক্তি এখানে উত্থাপিত ব্যতিক্রমটিকে ডেমো করছে।
নিউ আলেকজান্দ্রিয়া

11

ইয়াহুদা কাটজ " রুবির মধ্যে মেটাপোগ্র্যামিং: ইটস অল দ্য দ্য সেল্ফ " -এর সূক্ষ্মতাগুলি ব্যাখ্যা করার জন্য বেশ ভাল কাজ করেছেন


7
সাবটাইটেল বা ... সূক্ষ্মতা? ;)
অশ্বত্যাগী

দো :) এটি স্থির করার জন্য ধন্যবাদ, এখনই ঠিক করা হয়েছে।
পিট হজসন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.