রুবিতে @@ ভেরিয়েবলের অর্থ কী?


162

ডাবল এট চিহ্নের আগে রুবি ভেরিয়েবলগুলি কী কী (@@ ) এর ? একটি অ্যাট সাইন সহ পূর্ববর্তী ভেরিয়েবল সম্পর্কে আমার বোধগম্যতা হ'ল এটি পিএইচপি-তে এর মতো একটি উদাহরণ ভেরিয়েবল:

পিএইচপি সংস্করণ

class Person {

    public $name;

    public function setName($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

রুবি সমতুল্য

class Person

    def set_name(name)
        @name = name
    end

    def get_name()
        @name
    end
end

ডাবল এট চিহ্নটির @@অর্থ কী, এবং কীভাবে এটি চিহ্নের একক থেকে পৃথক হয়?


103
আমি জানি না, তবে আমার কাছে অনুভূতিটি পেয়েছে। আমি এখন রুবিতে কোড করতে কিছুটা ভয়
পেয়েছি

2
টিএল; জনসাধারণের জন্য ডিআর: 100 এর মধ্যে 99 বার, আমি "শ্রেণীর উদাহরণ" ভেরিয়েবলগুলি ব্যবহার করব ( @অভ্যন্তরীণ selfপদ্ধতিগুলি) শ্রেণি ভেরিয়েবল ( @@) নয়। নীচের উত্তরে কেন কারণের লিটানি দেখুন।
ওয়াটসআইনাবক্স

উত্তর:


240

প্রিফিক্সযুক্ত একটি ভেরিয়েবল @হ'ল একটি উদাহরণ ভেরিয়েবল , যখন একটির সাথে উপসর্গ করা @@হয় একটি শ্রেণি ভেরিয়েবল । নিম্নলিখিত উদাহরণটি দেখুন; এর আউটপুটটি putsলাইনের শেষে মন্তব্যে রয়েছে:

class Test
  @@shared = 1

  def value
    @@shared
  end

  def value=(value)
    @@shared = value
  end
end

class AnotherTest < Test; end

t = Test.new
puts "t.value is #{t.value}" # 1
t.value = 2
puts "t.value is #{t.value}" # 2

x = Test.new
puts "x.value is #{x.value}" # 2

a = AnotherTest.new
puts "a.value is #{a.value}" # 2
a.value = 3
puts "a.value is #{a.value}" # 3
puts "t.value is #{t.value}" # 3
puts "x.value is #{x.value}" # 3

আপনি @@sharedক্লাসের মধ্যে ভাগ করা দেখতে পারেন ; একের উদাহরণে মান নির্ধারণ করা class শ্রেণীর এবং এমনকি শিশু শ্রেণীর সমস্ত অন্যান্য দৃষ্টান্তের জন্য মান পরিবর্তন করে, যেখানে একটি ভেরিয়েবল, যার @sharedসাথে একটি থাকে @না would

[হালনাগাদ]

Phrogz মন্তব্য উল্লেখ করেছে, এটা রুবি একটি সাধারণ বাগ্ধারা একটি দৃষ্টান্ত পরিবর্তনশীল সঙ্গে ক্লাস-স্তরের ডেটা ট্র্যাক করতে এর বর্গ নিজেই । আপনার মনকে চারপাশে মুড়িয়ে দেওয়ার জন্য এটি একটি জটিল বিষয় হতে পারে এবং এ বিষয়ে প্রচুর অতিরিক্ত পড়া আছে, তবে এটি Classক্লাসটি সংশোধনকারী হিসাবে ভাবুন তবে আপনি যে ক্লাসটির সাথে কাজ করছেন তার কেবলমাত্র উদাহরণ Class। একটি উদাহরণ:

class Polygon
  class << self
    attr_accessor :sides
  end
end

class Triangle < Polygon
  @sides = 3
end

class Rectangle < Polygon
  @sides = 4
end

class Square < Rectangle
end

class Hexagon < Polygon
  @sides = 6
end

puts "Triangle.sides:  #{Triangle.sides.inspect}"  # 3
puts "Rectangle.sides: #{Rectangle.sides.inspect}" # 4
puts "Square.sides:    #{Square.sides.inspect}"    # nil
puts "Hexagon.sides:   #{Hexagon.sides.inspect}"   # 6

আমি Squareউদাহরণটি অন্তর্ভুক্ত করেছি (যা ফলাফলগুলি nil) এটি দেখানোর জন্য যে এটি আপনার প্রত্যাশার সাথে 100% আচরণ করবে না; নিবন্ধটি আমি উপরের লিঙ্ক বিষয়ে অতিরিক্ত তথ্য প্রচুর হয়েছে।

এছাড়াও মনে রাখবেন যে, বেশিরভাগ ডেটার মতোই, ডার্কো-র মতামত অনুসারে, বহুবিবাহিত পরিবেশে আপনার ক্লাস ভেরিয়েবলগুলি সম্পর্কে অত্যন্ত সতর্ক হওয়া উচিত ।


1
এই উত্তরটি হ'ল আইএমএইচও হবে যদি আপনি কোডটি অন্তর্ভুক্ত করেন তবে কীভাবে আপনি শ্রেণীর স্তরের ডেটা ভাগ করে নেওয়ার 'অদ্ভুত' আচরণ ছাড়াই শ্রেণি-স্তরের ডেটা ট্র্যাক করতে ক্লাস স্তরে কোনও উদাহরণ পরিবর্তনশীল ব্যবহার করতে পারেন showing
ফ্রোগজ

3
আমি আরও উল্লেখ করতে পারি যে ক্লাসের ভেরিয়েবলগুলি একাধিক-থ্রেড পরিবেশে (যেমন
রেলগুলি

হুম ... একরকমভাবে এটি পিএইচপি-তে স্থির ভেরিয়েবলগুলির মতো শোনাচ্ছে তবে উত্তরাধিকারের অংশটি আলাদা। আমার মনে হয় না পিএইচপি-তে ঠিক এরকম কিছু রয়েছে।
অ্যান্ড্রু

5
আমি বুঝতে পারি না ruby class << self endব্লকটি কী করে, বিশেষত << অপারেটর।
ডেভিডিটসু

1
অন্যদের যে বিভ্রান্ত সম্পর্কে class << selfদেখতে এই
kapad

37

@- ক্লাসের ইনস্ট্যান্স ভেরিয়েবল
@@- ক্লাস ভেরিয়েবল, কিছু ক্ষেত্রে স্থির পরিবর্তনশীল হিসাবেও ডাকা হয়

ক্লাস ভেরিয়েবল এমন একটি চলক যা শ্রেণীর সমস্ত দৃষ্টান্তের মধ্যে ভাগ করা হয়। এর অর্থ এই শ্রেণি থেকে ইনস্ট্যান্ট করা সমস্ত বস্তুর জন্য কেবলমাত্র একটি পরিবর্তনশীল মান বিদ্যমান exists যদি কোনও অবজেক্ট উদাহরণটি ভেরিয়েবলের মান পরিবর্তন করে, তবে নতুন মানটি অন্য সমস্ত বস্তুর দৃষ্টান্তের জন্য মূলত পরিবর্তিত হবে।

ক্লাসের ভেরিয়েবলগুলি চিন্তা করার আরেকটি উপায় হ'ল একক শ্রেণির প্রেক্ষাপটে বৈশ্বিক পরিবর্তনশীল। দুটি @অক্ষর ( @@) সহ ভেরিয়েবলের নাম উপস্থাপন করে শ্রেণি ভেরিয়েবলগুলি ঘোষণা করা হয় । শ্রেণির ভেরিয়েবলগুলি তৈরির সময় শুরু করতে হবে


10

@@ শ্রেণীর পরিবর্তনশীল বোঝায়, এটি উত্তরাধিকার সূত্রে প্রাপ্ত হতে পারে।

এর অর্থ হ'ল আপনি যদি সেই শ্রেণীর একটি সাবক্লাস তৈরি করেন তবে এটি ভেরিয়েবলের উত্তরাধিকারী হবে। সুতরাং আপনার যদি Vehicleক্লাস ভেরিয়েবলের সাথে ক্লাস @@number_of_wheelsথাকে তবে আপনি যদি একটি তৈরি করেন class Car < Vehicleতবে এতেও ক্লাস ভেরিয়েবল থাকবে@@number_of_wheels


এর অর্থ হ'ল আপনি যদি সেই শ্রেণীর একটি সাবক্লাস তৈরি করেন তবে এটি ভেরিয়েবলের উত্তরাধিকারী হবে। সুতরাং আপনার যদি Vehicleক্লাস ভেরিয়েবলের সাথে ক্লাস @@number_of_wheelsথাকে তবে আপনি যদি class Car < Vehicleএটি তৈরি করেন তবে @@number_of_wheels
এতেও

12
যদি আমার class Vehicleসাথে থাকে @number_of_wheelsতবে তারপরে class Car < Vehicleএকটি উদাহরণ ভেরিয়েবলও থাকবে @number_of_wheels। ক্লাস ভেরিয়েবলের সাথে মূল পার্থক্য হ'ল ক্লাসগুলির একই ভেরিয়েবল থাকে, যেমন একটি পরিবর্তন করা অন্যকে পরিবর্তন করে।
মিশেল টিলে

1

@ এবং @@ মডিউলগুলিতেও আলাদাভাবে কাজ করা হয় যখন কোনও শ্রেণি সেই মডিউলটি প্রসারিত করে বা অন্তর্ভুক্ত করে।

তাই দেওয়া হয়েছে

module A
    @a = 'module'
    @@a = 'module'

    def get1
        @a          
    end     

    def get2
        @@a         
    end     

    def set1(a) 
        @a = a      
    end     

    def set2(a) 
        @@a = a     
    end     

    def self.set1(a)
        @a = a      
    end     

    def self.set2(a)
        @@a = a     
    end     
end 

তারপরে আপনি নীচের আউটপুটগুলি মন্তব্য হিসাবে দেখিয়েছেন

class X
    extend A

    puts get1.inspect # nil
    puts get2.inspect # "module"

    @a = 'class' 
    @@a = 'class' 

    puts get1.inspect # "class"
    puts get2.inspect # "module"

    set1('set')
    set2('set')

    puts get1.inspect # "set" 
    puts get2.inspect # "set" 

    A.set1('sset')
    A.set2('sset')

    puts get1.inspect # "set" 
    puts get2.inspect # "sset"
end 

class Y
    include A

    def doit
        puts get1.inspect # nil
        puts get2.inspect # "module"

        @a = 'class'
        @@a = 'class'

        puts get1.inspect # "class"
        puts get2.inspect # "class"

        set1('set')
        set2('set')

        puts get1.inspect # "set"
        puts get2.inspect # "set"

        A.set1('sset')
        A.set2('sset')

        puts get1.inspect # "set"
        puts get2.inspect # "sset"
    end
end

Y.new.doit

সুতরাং আপনার সমস্ত ব্যবহারের জন্য সাধারণ হিসাবে চলকগুলির জন্য মডিউলগুলিতে @@ ব্যবহার করুন এবং প্রতিটি ব্যবহারের প্রসঙ্গে আপনি পৃথক চান এমন ভেরিয়েবলের জন্য মডিউলগুলিতে @ ব্যবহার করুন।


1

উত্তরগুলি আংশিকভাবে সঠিক কারণ @@ আসলে একটি শ্রেণি পরিবর্তনশীল যা প্রতি শ্রেণীবৃত্ত হয় যার অর্থ এটি একটি শ্রেণীর দ্বারা ভাগ করা হয়, এর উদাহরণগুলি এবং তার বংশধর শ্রেণি এবং তাদের উদাহরণগুলি।

class Person
  @@people = []

  def initialize
    @@people << self
  end

  def self.people
    @@people
  end
end

class Student < Person
end

class Graduate < Student
end

Person.new
Student.new

puts Graduate.people

এই আউটপুট হবে

#<Person:0x007fa70fa24870>
#<Student:0x007fa70fa24848>

সুতরাং ব্যক্তি, শিক্ষার্থী এবং স্নাতক শ্রেণীর জন্য একমাত্র একই @@ ভেরিয়েবল এবং এই শ্রেণীর সমস্ত শ্রেণি এবং উদাহরণ পদ্ধতিগুলি একই ভেরিয়েবলের উল্লেখ করে।

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

class Person

  def initialize
    self.class.add_person self
  end

  def self.people
    @people
  end

  def self.add_person instance
    @people ||= []
    @people << instance
  end
end

class Student < Person
end

class Graduate < Student
end

Person.new
Person.new
Student.new
Student.new
Graduate.new
Graduate.new

puts Student.people.join(",")
puts Person.people.join(",")
puts Graduate.people.join(",")

এখানে, @ শ্রেণি শ্রেণিবিন্যাসের পরিবর্তে জনগণ প্রতি ক্লাসে একক কারণ এটি প্রতিটি শ্রেণীর উদাহরণগুলিতে আসলে পরিবর্তনশীল stored এটি আউটপুট:

#<Student:0x007f8e9d2267e8>,#<Student:0x007f8e9d21ff38>
#<Person:0x007f8e9d226158>,#<Person:0x007f8e9d226608>
#<Graduate:0x007f8e9d21fec0>,#<Graduate:0x007f8e9d21fdf8> 

একটি গুরুত্বপূর্ণ পার্থক্য হ'ল আপনি উদাহরণস্বরূপ পদ্ধতিগুলি থেকে সরাসরি এই শ্রেণীর ভেরিয়েবলগুলি (বা শ্রেণীর উদাহরণের ভেরিয়েবলগুলি বলতে পারবেন) অ্যাক্সেস করতে পারবেন না কারণ একটি উদাহরণ পদ্ধতিতে লোকজন ব্যক্তি বা শিক্ষার্থী বা স্নাতক শ্রেণীর সেই নির্দিষ্ট উদাহরণের একটি উদাহরণ পরিবর্তনশীলকে বোঝায় ।

সুতরাং অন্য উত্তরগুলি সঠিকভাবে জানিয়েছে যে @myvariable (একক @ স্বরলিপি সহ) সর্বদা একটি উদাহরণ পরিবর্তনশীল, এর অর্থ এই নয় যে এই শ্রেণীর সমস্ত দৃষ্টান্তের জন্য এটি একক ভাগের পরিবর্তনশীল নয়।

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