বর্গ ভেরিয়েবল এবং শ্রেণীর উদাহরণ ভেরিয়েবলের মধ্যে পার্থক্য?


91

ক্লাস ভেরিয়েবল এবং ক্লাস উদাহরণ ভেরিয়েবলের মধ্যে পার্থক্য সম্পর্কে কেউ কি আমাকে বলতে পারবেন?

উত্তর:


152

ক্লাস ভেরিয়েবল ( @@) শ্রেণি এবং এর সমস্ত বংশধরের মধ্যে ভাগ করা হয়। শ্রেণীর উদাহরণ পরিবর্তনশীল ( @) শ্রেণীর বংশধরদের দ্বারা ভাগ করা হয় না।


ক্লাস ভেরিয়েবল ( @@)

আসুন একটি ক্লাস ভেরিয়েবল সহ একটি ক্লাস ফু রাখি @@iএবং পড়তে এবং লেখার জন্য অ্যাক্সেসরগুলি পাই @@i:

class Foo

  @@i = 1

  def self.i
    @@i
  end

  def self.i=(value)
    @@i = value
  end

end

এবং প্রাপ্ত একটি বর্গ:

class Bar < Foo
end

আমরা দেখতে পাই যে ফু এবং বারের জন্য একই মূল্য রয়েছে @@i:

p Foo.i    # => 1
p Bar.i    # => 1

এবং @@iএকটিতে পরিবর্তন করা উভয় ক্ষেত্রেই এটি পরিবর্তন করে:

Bar.i = 2
p Foo.i    # => 2
p Bar.i    # => 2

শ্রেণীর উদাহরণ পরিবর্তনশীল ( @)

আসুন একটি সাধারণ শ্রেণি তৈরি করি যা ক্লাস উদাহরণের সাথে পরিবর্তনশীল @iএবং পড়া এবং লেখার জন্য অ্যাক্সেসর রয়েছে @i:

class Foo

  @i = 1

  def self.i
    @i
  end

  def self.i=(value)
    @i = value
  end

end

এবং প্রাপ্ত একটি বর্গ:

class Bar < Foo
end

আমরা দেখতে পাই যে বারের জন্য অ্যাক্সেসরদের উত্তরাধিকারসূত্রে পাওয়া @iগেলেও এটি নিজের উত্তরাধিকার সূত্রে আসে না @i:

p Foo.i    # => 1
p Bar.i    # => nil

@iফু এর উপর প্রভাব না ফেলেই আমরা বার সেট করতে পারি @i:

Bar.i = 2
p Foo.i    # => 1
p Bar.i    # => 2

4
ক্লাসের পদ্ধতি ব্যবহার করে পুনরায় উদাহরণের পরিবর্তনশীল কেন? আপনি কি এই পরিস্থিতিতে প্রায়শই দৌড়ান?
সেকমো

4
@ সেকমো এই উদাহরণগুলিতে অ্যাক্সেসররা শ্রেণীর উদাহরণ ভেরিয়েবলগুলি প্রদান করে যা শ্রেণীর অন্তর্গত, বা শ্রেণীর ভেরিয়েবল , যা শ্রেণিবৃত্তির অন্তর্গত। তারা ক্লাসের উদাহরণগুলির সাথে সম্পর্কিত যে সরল উদাহরণের ভেরিয়েবলগুলি ফেরত দেয় না । "দৃষ্টান্ত পরিবর্তনশীল," "শ্রেণীর উদাহরণ পরিবর্তনযোগ্য," এবং "শ্রেণি ভেরিয়েবল" পদগুলি বেশ বিভ্রান্তিকর, তাই না?
ওয়েন কনরাড

72

প্রথমে আপনাকে অবশ্যই বুঝতে হবে যে ক্লাসগুলিও উদাহরণ - শ্রেণীর উদাহরণ Class

একবার আপনি এটি বুঝতে পারলে, আপনি বুঝতে পারবেন যে কোনও শ্রেণীর সাথে নিয়মিত (পড়ুন: নন-শ্রেণি) অবজেক্ট যেমন পারে তেমনভাবে উদাহরণের সাথে ভেরিয়েবল যুক্ত থাকতে পারে।

Hello = Class.new

# setting an instance variable on the Hello class
Hello.instance_variable_set(:@var, "good morning!")

# getting an instance variable on the Hello class
Hello.instance_variable_get(:@var) #=> "good morning!"

মনে রাখবেন যে, উপর একটি দৃষ্টান্ত পরিবর্তনশীল Helloএকটি অন সম্পূর্ণরূপে একটি দৃষ্টান্ত পরিবর্তনশীল থেকে সম্পর্কহীন এবং স্বতন্ত্র উদাহরণস্বরূপ এরHello

hello = Hello.new

# setting an instance variable on an instance of Hello
hello.instance_variable_set(:@var, :"bad evening!")

# getting an instance variable on an instance of Hello
hello.instance_variable_get(:@var) #=> "bad evening!")

# see that it's distinct from @var on Hello
Hello.instance_variable_get(:@var) #=> "good morning!"

একটি বর্গ পরিবর্তনশীল অন্যদিকে, দুই উপরে সমন্বয় এক ধরনের যেমন অ্যাক্সেসযোগ্য Hello, নিজেই এবং তার দৃষ্টান্ত হিসাবে ভাল এর উপশ্রেণী হিসাবে Helloএবং তাদের দৃষ্টান্ত:

HelloChild = Class.new(Hello)
Hello.class_variable_set(:@@class_var, "strange day!")
hello = Hello.new
hello_child = HelloChild.new

Hello.class_variable_get(:@@class_var) #=> "strange day!"
HelloChild.class_variable_get(:@@class_var) #=> "strange day!"
hello.singleton_class.class_variable_get(:@@class_var) #=> "strange day!"
hello_child.singleton_class.class_variable_get(:@@class_Var) #=> "strange day!"

class variablesউপরের অদ্ভুত আচরণের কারণে অনেকে এড়াতে বলে এবং class instance variablesপরিবর্তে এর ব্যবহারের পরামর্শ দেয় ।


4
+1 সুপার ব্যাখ্যা! এটি এমন কিছু যা রুবির কাছে নতুন প্রতিটি প্রোগ্রামার হজম করে।
টমজ

0

এছাড়াও আমি যোগ করতে চাই আপনি ক্লাসের যে @@কোনও উদাহরণ থেকে ক্লাস ভেরিয়েবল ( ) এ অ্যাক্সেস পেতে পারেন

class Foo
  def set_name
    @@name = 'Nik'
  end

  def get_name
    @@name
  end
end


a = Foo.new
a.set_name
p a.get_name # => Nik
b = Foo.new
p b.get_name # => Nik

কিন্তু আপনি ক্লাস উদাহরণ চলক ( @) এর জন্য একই করতে পারবেন না

class Foo
  def set_name
    @name = 'Nik'
  end

  def get_name
    @name
  end
end


a = Foo.new
a.set_name
p a.get_name # => Nik
b = Foo.new
p b.get_name # => nil

-1: এটি ভুল: শ্রেণীর উদাহরণের ভেরিয়েবলগুলি সেই শ্রেণীর প্রতিটি উদাহরণ থেকে অ্যাক্সেস করা যায় (শর্ত থাকে যে অ্যাক্সেসররা উপস্থিত আছেন)। তদ্ব্যতীত, আপনার উদাহরণটি নিয়মিত উদাহরণ ভেরিয়েবলগুলি দেখায়, শ্রেণীর উদাহরণের ভেরিয়েবলগুলি নয়। শ্রেণীর উদাহরণের ভেরিয়েবলগুলি পদ্ধতির বাইরে ঘোষণা করা হয় এবং নিয়মিত উদাহরণ ভেরিয়েবল এবং বর্গ ভেরিয়েবল উভয়ের থেকে মৌলিকভাবে পৃথক।
পেলমিস্টার

আপনি কীভাবে সেই শ্রেণীর প্রতিটি উদাহরণ থেকে ক্লাস ইনস্ট্যান্স ভেরিয়েবল অ্যাক্সেস পেতে পারেন?
ইভান রস

আপনি ওয়েন কনরাডের উত্তরটি পড়েছেন? এটি আক্ষরিকভাবে এটি ব্যাখ্যা করে। stackoverflow.com/a/3803089/439592
Pellmeister

আমি জানি আপনি ক্লাসের পদ্ধতি থেকে যেমন অ্যাক্সেস পেতে পারেন Foo.iতবে আপনি এই ক্লাসের প্রতিটি উদাহরণের জন্য কীভাবে একই কাজ করতে পারেন Foo.new.i?
ইভান রস

ব্যবহার করে #class। আমি ব্যক্তিগতভাবে মনে করি যে #classকোনও কিছুর জন্য ডাকা selfহলেও ব্যবহারযোগ্য তবে কোডটি গন্ধযুক্ত। এমনকি আপনি এক পা এগিয়ে যান এবং উদাহরণ হিসেবে বলা যায় accessors বাস্তবায়ন করতে পারে iএবং i=তাদের যে প্রতিনিধি #classসমতুল, যে ক্ষেত্রে আপনি কি করতে পারেন Foo.new.i। আমি এটি করার প্রস্তাব দিচ্ছি না কারণ এটি একটি বিভ্রান্তিকর ইন্টারফেস তৈরি করে, যা আপনি কোনও অবজেক্ট সদস্যকে সংশোধন করছেন।
পেলমিস্টার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.