अपरिवर्तनीय वस्तु

From Vigyanwiki

ओब्जेक्ट-उन्मुख कंप्यूटर प्रोग्रामिंग में ओब्जेक्ट-उन्मुख और कार्यात्मक प्रोग्रामिंग अपरिवर्तनीय ओब्जेक्ट (अपरिवर्तनीय[1] ऑब्जेक्ट) ऑब्जेक्ट कंप्यूटर विज्ञान है, जिसकी स्थिति बनने के पश्चात उसे संशोधित नहीं किया जा सकता है।[2] यह परिवर्तनशील ओब्जेक्ट परिवर्तनशील ओब्जेक्ट के विपरीत रहती हैं, जिसे बनने के बाद संशोधित किया जा सकता है। [3] कुछ स्थितियों में ओब्जेक्ट को अपरिवर्तनीय माना जाता है, भले ही कुछ आंतरिक रूप से उपयोग की जाने वाली विशेषताएँ परिवर्तित हो जाती हैं, किन्तु किसी ओब्जेक्ट की स्थिति उसके बाहरी दृष्टिकोण से अपरिवर्तित दिखाई देती है। उदाहरण के लिए वह ओब्जेक्ट जो उपयोगी है मुख्य रूप से महंगी संगणनाओं के परिणामों को कैश करने के लिए संस्मरण अभी भी अपरिवर्तनीय ओब्जेक्ट के रूप में माना जाता हैं।

ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग में पठनीयता और रनटाइम दक्षता में सुधार के लिए स्ट्रिंग्स और अन्य ठोस ओब्जेक्ट्स को सामान्यतः अपरिवर्तनीय ओब्जेक्ट्स के रूप में व्यक्त किया जाता है। अपरिवर्तनीय ओब्जेक्टएँ भी उपयोगी होती हैं क्योंकि वे स्वाभाविक रूप से थ्रेड सुरक्षा या थ्रेड्स के लिए सुरक्षित होती हैं।[2] इसके अन्य लाभ यह हैं कि वे समझने में सरल होती हैं और उनके बारे में तर्क किया जा सकता हैं जो परिवर्तनशील ओब्जेक्ट्स की तुलना में उच्च सुरक्षा प्रदान करते हैं।[2]

अवधारणाएं

अपरिवर्तनीय चर

अनिवार्य प्रोग्रामिंग में, फंक्शन चर्स में रखे गए मान जिनकी सामग्री कभी नहीं परिवर्तित कर सकते हैं, उन्हें कॉन्स्टेंट (प्रोग्रामिंग) के रूप में जाना जाता है जिससे कि उन्हें वेरिएबल्स से पृथक किया जा सके जो निष्पादन के समय परिवर्तित किये जा सकते हैं। उदाहरण के रूप में मीटर से फ़ुट तक रूपांतरण का कारक या पाई का मान कई दशमलव स्थानों तक सम्मिलित रहता हैं।

रीड-ओनली फ़ील्ड की गणना तब की जाती है जब प्रोग्राम रन होता हैं इसके स्थिरांक के विपरीत जो पहले से ज्ञात रहता हैं, किन्तु आरंभ होने के पश्चात कभी परिवर्तित नहीं होते हैं।

कमजोर बनाम मजबूत अपरिवर्तनीयता

कभी-कभी किसी ओब्जेक्ट्स के कुछ क्षेत्रों में अपरिवर्तनीय होने की बात होती हैं। इसका अर्थ है कि ओब्जेक्ट स्थिति के उन भागों को परिवर्तित करने की कोई विधि नहीं है, भले ही ओब्जेक्ट के अन्य भाग परिवर्तनशील (कमजोर रूप से अपरिवर्तनीय) हो सकते हैं। यदि सभी क्षेत्र अपरिवर्तनीय हों जाए तो ओब्जेक्ट अपरिवर्तनीय हो जाती हैं। यदि संपूर्ण ओब्जेक्ट को किसी अन्य वर्ग द्वारा विस्तारित नहीं किया जा सकता है, तो ओब्जेक्ट को दृढ़ता से अपरिवर्तनीय कहा जाता है।[4] इसके मुख्य उदाहरण के लिए, ओब्जेक्ट के जीवनकाल के माध्यम से समान रहने वाली ओब्जेक्ट में कुछ निश्चित डेटा के बारे में स्पष्ट रूप से लागू करने में सहायता कर सकता है। कुछ भाषाओं में, यह कीवर्ड के साथ किया जाता है (उदा. const सी ++ में, final जावा (प्रोग्रामिंग भाषा) में) जो क्षेत्र को अपरिवर्तनीय के रूप में निर्दिष्ट करता है। कुछ भाषाएं इसे व्युत्क्रम कर दिया जाता हैं: OCaml में, किसी ओब्जेक्ट या रिकॉर्ड के क्षेत्र डिफ़ॉल्ट रूप से अपरिवर्तनीय होते हैं, और इन्हें स्पष्ट रूप से चिह्नित किया जाना चाहिए जो मुख्य रूप से mutable होने चाहिए।

ओब्जेक्ट्स के संदर्भ

अधिकांश ओब्जेक्ट-उन्मुख प्रोग्रामिंग भाषा या ऑब्जेक्ट-ओरिएंटेड लैंग्वेज में, ऑब्जेक्ट्स को रेफरेंस (कंप्यूटर विज्ञान) का उपयोग करके संदर्भित किया जा सकता है। ऐसी भाषाओं के कुछ उदाहरण जावा (प्रोग्रामिंग भाषा), सी++, सी शार्प (प्रोग्रामिंग भाषा) या सी#, विजुअल बेसिक डाॅट नेट और कई स्क्रिप्टिंग भाषाएं उपलब्ध हैं, जैसे पर्ल, पायथन (प्रोग्रामिंग भाषा), और रूबी प्रोग्रामिंग भाषा इत्यादि। इस स्थिति में, इसका अर्थ होता है कि क्या किसी ओब्जेक्ट की स्थिति भिन्न हो सकती है जब ओब्जेक्ट्स को संदर्भों के माध्यम से साझा किया जाता है।

ओब्जेक्ट्स की नकल बनाम संदर्भ

यदि किसी ओब्जेक्ट को अपरिवर्तनीय माना जाता है, तो संपूर्ण ओब्जेक्ट की नकल करने के अतिरिक्त उसका संदर्भ (कंप्यूटर विज्ञान) बनाना पसंद किया जाता है। यह डेटा डुप्लीकेशन को रोककर और कंस्ट्रक्टर और डिस्ट्रक्टर्स को कॉल से बचने के लिए मेमोरी को संरक्षित करने के लिए किया जाता है, इसके परिणामस्वरूप निष्पादन की गति में संभावित वृद्धि होती है।

म्यूटेबल ऑब्जेक्ट्स के लिए संदर्भ प्रतिलिपि विधि का उपयोग करना अधिक कठिन है, क्योंकि यदि किसी म्यूटेबल ऑब्जेक्ट संदर्भ के किसी भी उपयोगकर्ता ने इसे परिवर्तित कर दिया जाता हैं, तो उस संदर्भ के अन्य सभी उपयोगकर्ता परिवर्तन देख सकते हैं। यदि यह वांछित प्रभाव नहीं है, तो अन्य उपयोगकर्ताओं को सही ढंग से प्रतिक्रिया देने के लिए सूचित करना कठिन हो सकता है। इन स्थितियों में, संदर्भ के अतिरिक्त संपूर्ण ओब्जेक्ट की रक्षात्मक प्रतिलिपि बनाना सामान्यतः सरल किन्तु महंगा समाधान होता है। प्रेक्षक पैटर्न परिवर्तनशील ओब्जेक्ट्स में परिवर्तन को संभालने के लिए वैकल्पिक विधि है।

लिखने पर नकल

इस प्रकार की विधि को परिवर्तनीय और अपरिवर्तनीय ओब्जेक्ट्स के लाभों को मिश्रित किया जाता हैं, और लगभग सभी आधुनिक हार्डवेयर में सीधे समर्थित करते हैं, इसकी कॉपी-ऑन-राइट (COW) की जा सकती हैं। इस विधि का उपयोग करते हुए जब कोई उपयोगकर्ता सिस्टम को ऑब्जेक्ट कॉपी करने के लिए कहता है, तो यह केवल नये संदर्भ को बनाता है जो अभी भी उसी ऑब्जेक्ट को इंगित करता है। जैसे ही कोई उपयोगकर्ता किसी विशेष संदर्भ के माध्यम से ओब्जेक्ट को संशोधित करने का प्रयास करता है, इस प्रकार की प्रणाली वास्तविक प्रति बनाता है, उस पर संशोधन लागू करता है, और नई प्रतिलिपि को संदर्भित करने के लिए संदर्भ सेट करता है। अन्य उपयोगकर्ता अप्रभावित हैं, क्योंकि वे अभी भी मूल ओब्जेक्ट को संदर्भित करते हैं। इसलिए, गाय के अनुसार, सभी उपयोगकर्ताओं को अपनी ओब्जेक्ट्स का परिवर्तनशील संस्करण दिखाई देता है, चूंकि इस स्थिति में कि उपयोगकर्ता अपनी ओब्जेक्ट्स को संशोधित नहीं करते हैं, अपरिवर्तनीय ओब्जेक्ट्स के स्थान-बचत और गति के लाभ संरक्षित हैं। इस प्रकार के कॉपी-ऑन-राइट वर्चुअल मेमोरी सिस्टम में लोकप्रिय है क्योंकि यह उन्हें मेमोरी स्पेस को बचाने की अनुमति देता है जबकि अभी भी किसी एप्लिकेशन प्रोग्राम को सही विधि से नियंत्रित कर सकता है।

इंटर्निंग

समान ओब्जेक्ट्स की प्रतियों के स्थान पर सदैव संदर्भों का उपयोग करने की प्रथा को इंटर्न (कंप्यूटर विज्ञान) के रूप में जाना जाता है। यदि इंटर्निंग का उपयोग किया जाता है, तो दो ओब्जेक्ट्स को समान माना जाता है यदि और केवल यदि उनके संदर्भ, सामान्यतः पॉइंटर्स या पूर्णांक के रूप में दर्शाए जाते हैं जो आपस में बराबर होते हैं। कुछ भाषाएँ स्वचालित रूप से ऐसा करती हैं: उदाहरण के लिए, पायथन (प्रोग्रामिंग भाषा) स्वचालित रूप से स्ट्रिंग इंटर्न पूल द्वारा उपयोग की जाती हैं। यदि एल्गोरिदम जो इंटर्निंग को लागू करता है, उसे हर स्थिति में ऐसा करने की गारंटी दी जाती है कि यह संभव है, तो समानता के लिए ओब्जेक्ट्स की तुलना उनके पॉइंटर्स की तुलना करने के लिए कम हो जाती है - अधिकांश अनुप्रयोगों में गति में पर्याप्त लाभ को प्रदर्शित करता हैं। यहां तक ​​​​कि यदि एल्गोरिदम व्यापक होने की गारंटी नहीं है, तब भी ओब्जेक्ट्स के बराबर होने और समान संदर्भ का उपयोग करने पर तेज़ पथ स्थिति में सुधार की संभावना सम्मिलित है। इंटर्निंग सामान्यतः केवल अपरिवर्तनीय ओब्जेक्ट्स के लिए उपयोगी होती है।

थ्रेड सुरक्षा

बहु-थ्रेडेड अनुप्रयोगों में अपरिवर्तनीय ओब्जेक्टएं उपयोगी हो सकती हैं। अन्य सूत की अलमारी द्वारा डेटा को परिवर्तित किए जाने की चिंता के बिना कई थ्रेड्स अपरिवर्तनीय ओब्जेक्ट्स द्वारा दर्शाए गए डेटा पर कार्य कर सकते हैं। इसलिए अपरिवर्तनीय ओब्जेक्ट्स को उत्परिवर्तनीय ओब्जेक्ट्स की तुलना में अधिक थ्रेड-सुरक्षित माना जाता है।

अपरिवर्तनीयता का उल्लंघन

अपरिवर्तनीयता का अर्थ यह नहीं है कि कंप्यूटर के कंप्यूटर भंडारण में संग्रहीत ओब्जेक्ट लिखने योग्य नहीं है। बल्कि अपरिवर्तनीयता संकलन-समय का निर्माण करते हैं जो इंगित करता है कि प्रोग्रामर ओब्जेक्ट के सामान्य इंटरफ़ेस के माध्यम से क्या कर सकता है, जरूरी नहीं कि वे बिल्कुल क्या कर सकते हैं (उदाहरण के लिए, टाइप सिस्टम को अलग करके या सी (प्रोग्रामिंग भाषा) में शुद्धता का उल्लंघन करके) या सी ++) का उपयोग करते हैं।

भाषा-विशिष्ट विवरण

पायथन (प्रोग्रामिंग लैंग्वेज), जावा (प्रोग्रामिंग लैंग्वेज) और .नेट फ्रेमवर्क में, स्ट्रिंग्स अपरिवर्तनीय ओब्जेक्टएं हैं। जावा और .नेट फ्रेमवर्क दोनों में स्ट्रिंग के परिवर्तनशील संस्करण हैं। जावा में ये StringBufferहोते हैं और StringBuilder (जावा के परिवर्तनशील संस्करण String) और .नेट में यह है StringBuilder (.नेट का परिवर्तनशील संस्करण String). पायथन 3 में परिवर्तनशील स्ट्रिंग (बाइट्स) संस्करण है, जिसका नाम है bytearray.[5] इसके अतिरिक्त, जावा में सभी वर्चुअल आवरण वर्ग अपरिवर्तनीय हैं।

इसी प्रकार के पैटर्न अपरिवर्तनीय इंटरफ़ेस और अपरिवर्तनीय आवरण हैं।

इस प्रकार शुद्ध कार्यात्मक प्रोग्रामिंग भाषाओं में भाषा को विस्तारित किए बिना परिवर्तनीय ओब्जेक्ट्स को बनाना संभव नहीं है (उदाहरण के लिए परिवर्तनीय संदर्भ लाइब्रेरी या विदेशी फ़ंक्शन इंटरफ़ेस के माध्यम से), इसलिए सभी ऑब्जेक्ट अपरिवर्तनीय हैं।

एडीए

एडीए (प्रोग्रामिंग लैंग्वेज) में, किसी भी ओब्जेक्ट को या तो वैरिएबल घोषित किया जाता है (अर्थात परिवर्तनशील; सामान्यतः अंतर्निहित डिफ़ॉल्ट), या constant (अर्ताथ अपरिवर्तनीय) के माध्यम से constant कीवर्ड उपयोग किए जाते हैं।

  type Some_type is new Integer; -- could be anything more complicated
  x: constant Some_type:= 1; -- immutable
  y: Some_type; -- mutable

उपप्रोग्राम पैरामीटर इन मोड में अपरिवर्तनीय हैं, और आउट और आउट मोड में उत्परिवर्तनीय रहते हैं।

  procedure Do_it(a: in Integer; b: in out Integer; c: out Integer) is
  begin
    -- a is immutable
    b:= b + a;
    c:= a;
  end Do_it;


सी #

सी शार्प (प्रोग्रामिंग लैंग्वेज) या सी # में आप वर्ग के क्षेत्रों की अपरिवर्तनीयता को लागू कर सकते हैं, इस प्रकार readonly कथन के अनुसार इन सभी क्षेत्रों को अपरिवर्तनीयता के रूप में लागू करके, आप अपरिवर्तनीय प्रकार प्राप्त करते हैं।

class AnImmutableType
{
    public readonly double _value;
    public AnImmutableType(double x) 
    { 
        _value = x; 
    }
    public AnImmutableType Square() 
    { 
        return new AnImmutableType(_value * _value); 
    }
}

सी ++

सी ++ में, कॉन्स्ट-शुद्धता या कॉन्स्ट-सही कार्यान्वयन Cart उपयोगकर्ता को कक्षा के उदाहरण बनाने और फिर उनका उपयोग const द्वारा करने की अनुमति देता हैं, जो (अपरिवर्तनीय) या परिवर्तनशीलता पर निर्भर रहते हैं, जैसा कि वांछित है कि दो अलग-अलग संस्करण प्रदान करके उन्हें items() द्वारा संलग्न किया जाता हैं। (ध्यान दें कि सी ++ में यह जरूरी नहीं है - और वास्तव में असंभव - विशेष कन्स्ट्रक्टर प्रदान करने के लिए const उपयोग होता हैं।)

class Cart {
 public:
  Cart(std::vector<Item> items): items_(items) {}

  std::vector<Item>& items() { return items_; }
  const std::vector<Item>& items() const { return items_; }

  int ComputeTotalCost() const { /* return sum of the prices */ }

 private:
  std::vector<Item> items_;
};

ध्यान दें कि, जब कोई डेटा सदस्य होता है जो किसी अन्य ऑब्जेक्ट के लिए सूचक या संदर्भ होता है, तो केवल गैर-कॉन्स्ट विधि के भीतर इंगित या संदर्भित ऑब्जेक्ट को म्यूटेट करना संभव है।

C++ सार (बिटवाइज़ के विपरीत) के माध्यम से अपरिवर्तनीयता भी प्रदान करता है mutable कीवर्ड, जो सदस्य वैरिएबल को के भीतर const विधि से परिवर्तित होता है।

class Cart {
 public:
  Cart(std::vector<Item> items): items_(items) {}

  const std::vector<Item>& items() const { return items_; }

  int ComputeTotalCost() const {
    if (total_cost_) {
      return *total_cost_;
    }

    int total_cost = 0;
    for (const auto& item : items_) {
      total_cost += item.Cost();
    }
    total_cost_ = total_cost;
    return total_cost;
  }

 private:
  std::vector<Item> items_;
  mutable std::optional<int> total_cost_;
};

डी

डी प्रोग्रामिंग लैंग्वेज में, दो प्रकार के क्वालीफायर टाइप सम्मिलित होते हैं, जिसमें const और immutable इनमें मुख्य हैं, इन वेरिएबल्स के लिए जिन्हें परिवर्तित नहीं जा सकता हैं।[6] वे C++ के विपरीत const, के द्वारा आपको final, और सी# में readonly के सकर्मक रहते हैं और ऐसे वैरिएबल के संदर्भों के माध्यम से किसी भी चीज़ पर पुनरावर्ती रूप से लागू होते हैं। इनके बीच में अंतर const और immutable पर लागू होते हैं: const वैरिएबल की अवधारणा हैं: इस प्रकार संदर्भित मान के लिए परस्पर इसके संदर्भ में सम्मिलित हो सकते हैं, अर्थात इसके मान को वास्तव में परिवर्तित किया जा सकता है। इसके विपरीत, immutable निर्दिष्ट मान की संपत्ति है: इस मान के लिए और इससे संक्रमणीय रूप से पहुंचने योग्य कुछ भी परिवर्तित नहीं जा सकता है, इस प्रकार टाइप सिस्टम को तोड़ने के बिना, अपरिभाषित व्यवहार के लिए अग्रणी रहते हैं। उस मान के किसी भी संदर्भ को const या immutableद्वारा चिह्नित किया जाना चाहिए, इस प्रकार मूल रूप से किसी भी अयोग्य प्रकार के लिए T, const(T) का असंयुक्त संघ है T (परिवर्तनीय) और immutable(T).को उपयोग किया जाता हैं।

class C {
  /*mutable*/ Object mField;
    const     Object cField;
    immutable Object iField;
}

इस परिवर्तनशीलता के लिए C ओब्जेक्ट, उसका mField को लिखा जा सकता है। के लिए const(C) ओब्जेक्ट, mField संशोधित नहीं किया जा सकता, यह इनहेरिट करता है const; iField अभी भी अपरिवर्तनीय है क्योंकि यह गारंटी है जिसके लिए immutable(C), सभी क्षेत्रों के लिए अपरिवर्तनीय रहता हैं।

इस प्रकार के फंक्शन में:

void func(C m, const C c, immutable C i)
{ /* inside the braces */ }

ब्रेसिज़ के अंदर, c के रूप में ही ओब्जेक्ट को संदर्भित कर सकता है m, इसलिए उत्परिवर्तन m परोक्ष रूप से c द्वारा परिवर्तित हो सकता है,

c के रूप में ही ओब्जेक्ट को संदर्भित कर सकता है i, किन्तु चूंकि मूल्य अपरिवर्तनीय है, इसमें कोई परिवर्तन नहीं होता है। चूंकि, m और i कानूनी रूप से ही ओब्जेक्ट का उल्लेख नहीं किया जा सकता हैं।

इस गारंटी को म्यूटेबल बनाने की कोई गारंटी नहीं होती हैं (फ़ंक्शन ओब्जेक्ट को परिवर्तित कर सकता है), const केवल-बाहरी गारंटी है कि फ़ंक्शन कुछ भी परिवर्तित नहीं करेगा और

immutable द्विदिश गारंटी है (फ़ंक्शन मान परिवर्तित नहीं होगा और कॉल करने वाले को इसे परिवर्तित नहीं करना चाहिए)।

मान लेते हैं जो const या immutable हैं इसके लिए घोषणा के बिंदु (कंप्यूटर प्रोग्रामिंग) या कंस्ट्रक्टर (ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग) द्वारा प्रत्यक्ष असाइनमेंट द्वारा आरंभ किया जाना चाहिए।

क्योंकि const पैरामीटर भूल जाते हैं कि मान उत्परिवर्तनीय था या नहीं, समान निर्माण, inout, कार्य करता है, अर्थ में, परिवर्तनीय जानकारी के लिए वैरिएबल के रूप में उपयोग किए जाते हैं।

इस प्रकार का कार्य const(S) function(const(T)) रिटर्न const(S) उत्परिवर्तनीय, स्थिरांक और अपरिवर्तनीय तर्कों के लिए टाइप किए गए मान को प्रदर्शित करते हैं। इसके विपरीत, प्रकार का कार्य inout(S) function(inout(T)) रिटर्न S परिवर्तनशील के लिए T तर्क, const(S) के लिए const(T) मूल्य, और immutable(S) के लिए immutable(T) मान देते हैं।

अपरिवर्तनीय मानों को उत्परिवर्तनीय पर कास्ट करने से परिवर्तन पर अपरिभाषित व्यवहार होता है, भले ही मूल मूल्य उत्परिवर्तनीय मूल से प्रारंभ होता हो। अपरिवर्तनीय मूल्यों को अपरिवर्तनीय में कास्टिंग करना कानूनी हो सकता है जब बाद में कोई परिवर्तनीय संदर्भ नहीं रहता है। व्यंजक को उत्परिवर्तनीय (...) से अपरिवर्तनीय में परिवर्तित किया जा सकता है यदि व्यंजक अद्वितीय है और सभी व्यंजक जिन्हें यह सकर्मक रूप से संदर्भित करता है या तो अद्वितीय या अपरिवर्तनीय हैं।[6]यदि संकलक विशिष्टता साबित नहीं कर सकता है, तो कास्टिंग स्पष्ट रूप से की जा सकती है और यह सुनिश्चित करने के लिए प्रोग्रामर पर निर्भर है कि कोई परिवर्तनशील संदर्भ सम्मिलित नहीं है।

प्ररूप string के लिए उपनाम है immutable(char)[], अर्ताथ अपरिवर्तनीय पात्रों की स्मृति का टाइप किया हुए टुकड़े के रूप में प्रदर्शित होता हैं।[7] यहाँ पर सबस्ट्रिंग बनाना सस्ता है, क्योंकि यह सिर्फ पॉइंटर और फाइल की गई लंबाई को कॉपी और संशोधित करता है, और सुरक्षित है, क्योंकि अंतर्निहित डेटा को परिवर्तित नहीं कर सकता है। इस प्रकार की ओब्जेक्टएँ const(char)[] स्ट्रिंग्स को संदर्भित कर सकता है, किन्तु म्यूटेबल बफ़र्स को भी संलग्न करता हैं।

किसी स्थिरांक या अपरिवर्तनीय मान की उथली प्रतिलिपि बनाने से अपरिवर्तनीयता की बाहरी परत हट जाती है: अपरिवर्तनीय स्ट्रिंग की प्रतिलिपि बनाना (immutable(char[])) स्ट्रिंग देता है जिसे (immutable(char)[]) द्वारा प्रदर्शित करते हैं। इस प्रकार अपरिवर्तनीय सूचक और लंबाई की नकल की जाती है और यहाँ पर प्रतियां परस्पर रहती हैं। संदर्भित डेटा को कॉपी नहीं किया जाता हैं और इसके क्वालीफायर को immutable के उदाहरण में रखा गया है इस प्रकार गहरी प्रति बनाकर इसे हटाया जा सकता है, उदाहरण के लिए dup फंक्शन का उपयोग करते हैं

जावा

एक अपरिवर्तनीय ओब्जेक्ट String क्लास का उत्कृष्ट उदाहरण जावा है

String s = "ABC";
s.toLowerCase();

प्रक्रिया toLowerCase() डेटा एबीसी कि नहीं बदलता है इस प्रकार s को रोकना सरल हैं। इसके अतिरिक्त, नया स्ट्रिंग ऑब्जेक्ट तत्काल किया जाता है और इसके निर्माण के समय डेटा एबीसी दिया जाता है। इस स्ट्रिंग ऑब्जेक्ट का संदर्भ toLowerCase() द्वारा दिया जाता है। इस प्रकार स्ट्रिंग बनाने के लिए s डेटा सम्मिलित करें abc , अलग दृष्टिकोण की आवश्यकता होती है।

s = s.toLowerCase();

अब स्ट्रिंग s नई स्ट्रिंग ऑब्जेक्ट का संदर्भ देता है जिसमें abc सम्मिलित है। वर्ग स्ट्रिंग की घोषणा के सिंटैक्स में कुछ भी नहीं है जो इसे अपरिवर्तनीय के रूप में लागू करता है; बल्कि, स्ट्रिंग क्लास की कोई भी विधि उस डेटा को प्रभावित नहीं करती है जिसमें स्ट्रिंग ऑब्जेक्ट सम्मिलित है, इस प्रकार इसे अपरिवर्तनीय बना देता है।

कीवर्ड final (अंतिम (जावा)#अंतिम चर) का उपयोग अपरिवर्तनीय वर्चुअल प्रकार और ओब्जेक्ट संदर्भों को लागू करने में किया जाता है,[8] किन्तु यह स्वयं ओब्जेक्ट्स को अपरिवर्तनीय नहीं बना सकता है। नीचे उदाहरण देखें:

वर्चुअल प्रकार वैरिएबल (int, long, short, आदि) परिभाषित होने के बाद पुन: असाइन किया जा सकता है। इसके प्रयोग से final को इससे रक्षित किया जा सकता है।

int i = 42; //int is a primitive type
i = 43; // OK

final int j = 42;
j = 43; // does not compile. j is final so can't be reassigned

केवल का उपयोग करके संदर्भ प्रकारों को अपरिवर्तनीय नहीं बनाया जा सकता है final कीवर्ड का प्रयोग किया जाता हैं। इस प्रकार final केवल पुन: असाइनमेंट को रोकता है।

final MyObject m = new MyObject(); //m is of reference type
m.data = 100; // OK. We can change state of object m (m is mutable and final doesn't change this fact)
m = new MyObject(); // does not compile. m is final so can't be reassigned

वर्चुअल रैपर (Integer, Long, Short, Double, Float, Character, Byte, Boolean) भी सभी अपरिवर्तनीय हैं। कुछ सरल दिशानिर्देशों का पालन करके अपरिवर्तनीय कक्षाएं लागू की जा सकती हैं।[9]

जावास्क्रिप्ट

जावास्क्रिप्ट में, सभी वर्चुअल प्रकार (अपरिभाषित, अशक्त, बूलियन, संख्या, BigInt, स्ट्रिंग, प्रतीक) अपरिवर्तनीय हैं, किन्तु कस्टम ऑब्जेक्ट सामान्यतः परिवर्तनशील होते हैं।

function doSomething(x) { /* does changing x here change the original? */ };
var str = 'a string';
var obj = { an: 'object' };
doSomething(str);         // strings, numbers and bool types are immutable, function gets a copy
doSomething(obj);         // objects are passed in by reference and are mutable inside function
doAnotherThing(str, obj); // `str` has not changed, but `obj` may have.

किसी ओब्जेक्ट में अपरिवर्तनीयता का अनुकरण करने के लिए, गुणों को केवल-पढ़ने के लिए परिभाषित किया जा सकता है।

var obj = {};
Object.defineProperty(obj, 'foo', { value: 'bar', writable: false });
obj.foo = 'bar2'; // silently ignored

चूंकि, उपरोक्त दृष्टिकोण अभी भी नई संपत्तियों को जोड़ने देता है। वैकल्पिक रूप से, कोई सम्मिलिता ओब्जेक्ट्स को अपरिवर्तनीय बनाने के लिए Object.freeze का उपयोग कर सकता है।

var obj = { foo: 'bar' };
Object.freeze(obj);
obj.foo = 'bars'; // cannot edit property, silently ignored
obj.foo2 = 'bar2'; // cannot add property, silently ignored

ECMA262 के कार्यान्वयन के साथ, जावास्क्रिप्ट में अपरिवर्तनीय संदर्भ बनाने की क्षमता है जिसे पुन: असाइन नहीं किया जा सकता है। चूंकि, ए का उपयोग करना const घोषणा का अर्थ यह नहीं है कि रीड-ओनली रेफरेंस का मूल्य अपरिवर्तनीय है, बस नाम को नए मान को नहीं सौंपा जा सकता है।

const ALWAYS_IMMUTABLE = true;

try {
  ALWAYS_IMMUTABLE = false;
} catch (err) {
  console.log("Can't reassign an immutable reference.");
}

const arr = [1, 2, 3];
arr.push(4);
console.log(arr); // [1, 2, 3, 4]

प्रतिक्रिया (जावास्क्रिप्ट लाइब्रेरी) की प्रारंभ के बाद से जावास्क्रिप्ट में अपरिवर्तनीय स्थिति का उपयोग बढ़ती प्रवृत्ति बन गया है, जो फ्लक्स-जैसे राज्य प्रबंधन पैटर्न जैसे रेडक्स (जावास्क्रिप्ट लाइब्रेरी) का समर्थन करता है।[10]

पर्ल

पर्ल में, केवल सभी विशेषताओं को केवल पढ़ने के लिए घोषित करके मू लाइब्रेरी के साथ अपरिवर्तनीय वर्ग बना सकते हैं:

package Immutable;
use Moo;

has value => (
    is      => 'ro',   # read only
    default => 'data', # can be overridden by supplying the constructor with
                       # a value: Immutable->new(value => 'something else');
);

1;

इसे अपरिवर्तनीय वर्ग बनाने के लिए दो चरणों की आवश्यकता होती है: पहला, एक्सेसर्स बनाना (या तो स्वचालित रूप से या मैन्युअल रूप से) जो ओब्जेक्ट विशेषताओं के संशोधन को रोकता है, और दूसरा, उस वर्ग के उदाहरणों के उदाहरण डेटा के प्रत्यक्ष संशोधन को रोकता है (यह सामान्यतः हैश में संग्रहीत होता था) संदर्भ, और हैश के साथ लॉक किया जा सकता है :: इसका उपयोग के लॉक_हैश फ़ंक्शन के लिए किया जाता हैं:

package Immutable;
use strict;
use warnings;
use base qw(Class::Accessor);
# create read-only accessors
__PACKAGE__->mk_ro_accessors(qw(value));
use Hash::Util 'lock_hash';

sub new {
    my $class = shift;
    return $class if ref($class);
    die "Arguments to new must be key => value pairs\n"
        unless (@_ % 2 == 0);
    my %defaults = (
        value => 'data',
    );
    my $obj = {
        %defaults,
        @_,
    };
    bless $obj, $class;
    # prevent modification of the object data
    lock_hash %$obj;
}
1;

या, मैन्युअल रूप से लिखे गए एक्सेसर के साथ:

package Immutable;
use strict;
use warnings;
use Hash::Util 'lock_hash';

sub new {
    my $class = shift;
    return $class if ref($class);
    die "Arguments to new must be key => value pairs\n"
        unless (@_ % 2 == 0);
    my %defaults = (
        value => 'data',
    );
    my $obj = {
        %defaults,
        @_,
    };
    bless $obj, $class;
    # prevent modification of the object data
    lock_hash %$obj;
}

# read-only accessor
sub value {
    my $self = shift;
    if (my $new_value = shift) {
        # trying to set a new value
        die "This object cannot be modified\n";
    } else {
        return $self->{value}
    }
}
1;

पायथन

पायथन (प्रोग्रामिंग लैंग्वेज) में, कुछ बिल्ट-इन प्रकार (संख्या, बूलियन, स्ट्रिंग्स, टुपल्स, फ्रोजनसेट) अपरिवर्तनीय हैं, किन्तु कस्टम वर्ग सामान्यतः परिवर्तनशील होते हैं। वर्ग में अपरिवर्तनीयता का अनुकरण करने के लिए, अपवाद बढ़ाने के लिए विशेषता सेटिंग और विलोपन को ओवरराइड कर सकता है:

class ImmutablePoint:
    """An immutable class with two attributes 'x' and 'y'."""

    __slots__ = ['x', 'y']

    def __setattr__(self, *args):
        raise TypeError("Can not modify immutable instance.")

    __delattr__ = __setattr__

    def __init__(self, x, y):
        # We can no longer use self.value = value to store the instance data
        # so we must explicitly call the superclass
        super().__setattr__('x', x)
        super().__setattr__('y', y)

मानक लाइब्रेरी सहायक collections.namedtuple और typing.NamedTuple, पायथन 3.6 से आगे उपलब्ध, सरल अपरिवर्तनीय कक्षाएं बनाएं। निम्नलिखित उदाहरण मोटे तौर पर ऊपर के बराबर है, साथ ही कुछ टपल जैसी विशेषताएं हैं:

from typing import NamedTuple
import collections

Point = collections.namedtuple('Point', ['x', 'y'])

# the following creates a similar namedtuple to the above
class Point(NamedTuple):
    x: int
    y: int

पायथन 3.7 में पेश किया गया, dataclasses डेवलपर्स को फ्रोजन इंस्टेंसेस के साथ अपरिवर्तनीयता का अनुकरण करने की अनुमति देते हैं। यदि जमे हुए डेटाक्लास का निर्माण किया जाता है, dataclasses ओवरराइड करेगा __setattr__() और __delattr__() अप करने के लिए FrozenInstanceError यदि आह्वान किया गया हैं।

from dataclasses import dataclass

@dataclass(frozen=True)
class Point:
    x: int
    y: int

रैकेट

रैकेट (प्रोग्रामिंग भाषा) अपने कोर पेयर टाइप (cons cells) को अपरिवर्तनीय बनाकर अन्य स्कीम (प्रोग्रामिंग लैंग्वेज) के कार्यान्वयन से अधिक सीमा तक अलग हो जाता है। इसके अतिरिक्त, यह समानांतर परिवर्तनशील जोड़ी प्रकार प्रदान करता है mcons, mcar, set-mcar! इत्यादि। इसके अतिरिक्त कई अपरिवर्तनीय प्रकारों का समर्थन किया जाता है, उदाहरण के लिए, अपरिवर्तनीय तार और वैक्टर, और इनका बड़े पैमाने पर उपयोग किया जाता है। नई संरचनाएं डिफ़ॉल्ट रूप से अपरिवर्तनीय होती हैं, जब तक कि किसी फ़ील्ड को विशेष रूप से परिवर्तनशील घोषित नहीं किया जाता है, या संपूर्ण संरचना:

(struct foo1 (x y))             ; all fields immutable
(struct foo2 (x [y #:mutable])) ; one mutable field
(struct foo3 (x y) #:mutable)   ; all fields mutable

भाषा अपरिवर्तनीय हैश टेबल, कार्यात्मक रूप से कार्यान्वित और अपरिवर्तनीय शब्दकोशों का भी समर्थन करती है।

जंग

जंग की जंग (प्रोग्रामिंग भाषा) # स्वामित्व प्रणाली डेवलपर्स को अपरिवर्तनीय वैरिएबल घोषित करने और अपरिवर्तनीय संदर्भ पारित करने की अनुमति देती है। डिफ़ॉल्ट रूप से, सभी वैरिएबल और संदर्भ अपरिवर्तनीय हैं। परिवर्तनशील वैरिएबल और संदर्भ स्पष्ट रूप से इसके साथ बनाए गए हैं mut कीवर्ड।

लगातार आइटम जंग में सदैव अपरिवर्तनीय होते हैं।

// constant items are always immutable
const ALWAYS_IMMUTABLE: bool = true;

struct Object {
    x: usize,
    y: usize,
}

fn main() {
    // explicitly declare a mutable variable
    let mut mutable_obj = Object { x: 1, y: 2 };
    mutable_obj.x = 3; // okay

    let mutable_ref = &mut mutable_obj;
    mutable_ref.x = 1; // okay

    let immutable_ref = &mutable_obj;
    immutable_ref.x = 3; // error E0594

    // by default, variables are immutable
    let immutable_obj = Object { x: 4, y: 5 };
    immutable_obj.x = 6; // error E0596

    let mutable_ref2 = 
        &mut immutable_obj; // error E0596

    let immutable_ref2 = &immutable_obj;
    immutable_ref2.x = 6; // error E0594
    
}

स्कैला

स्काला (प्रोग्रामिंग भाषा) में, किसी भी इकाई (संक्षिप्त रूप से, बाध्यकारी) को उत्परिवर्तनीय या अपरिवर्तनीय के रूप में परिभाषित किया जा सकता है: घोषणा में, कोई भी उपयोग कर सकता है val (मान) अपरिवर्तनीय संस्थाओं के लिए और var (चर) परिवर्तनशील लोगों के लिए। ध्यान दें कि भले ही अपरिवर्तनीय बंधन को पुन: असाइन नहीं किया जा सकता है, फिर भी यह परिवर्तनीय ओब्जेक्ट को संदर्भित कर सकता है और उस ओब्जेक्ट पर उत्परिवर्तन विधियों को कॉल करना अभी भी संभव है: बाध्यकारी अपरिवर्तनीय है, किन्तु अंतर्निहित ओब्जेक्ट उत्परिवर्तनीय हो सकती है।

उदाहरण के लिए, निम्नलिखित कोड स्निपेट:

val maxValue = 100
var currentValue = 1

इसे अपरिवर्तनीय इकाई को परिभाषित करता है maxValue (पूर्णांक प्रकार संकलन-समय पर अनुमानित है) और उत्परिवर्तनीय इकाई currentValue नामित है

डिफ़ॉल्ट रूप से, संग्रह वर्ग जैसे List और Map अपरिवर्तनीय हैं, इसलिए अद्यतन-विधियाँ किसी सम्मिलिता को परिवर्तित करके इसके अतिरिक्त नया उदाहरण लौटाती हैं। चूंकि यह अक्षम लग सकता है, इन वर्गों के कार्यान्वयन और उनकी अपरिवर्तनीयता की गारंटी का अर्थ है कि नया उदाहरण सम्मिलिता नोड्स का पुन: उपयोग कर सकता है, जो विशेष रूप से प्रतियां बनाने के स्थिति में बहुत कुशल है।[11][better source needed]

यह भी देखें

संदर्भ

This article contains some material from the Perl Design Patterns Book

  1. "अपरिवर्तनीय विशेषण - परिभाषा, चित्र, उच्चारण और उपयोग नोट्स - OxfordLearnersDictionaries.com पर ऑक्सफोर्ड एडवांस्ड लर्नर्स डिक्शनरी". www.oxfordlearnersdictionaries.com.
  2. 2.0 2.1 2.2 Goetz et al. Java Concurrency in Practice. Addison Wesley Professional, 2006, Section 3.4. Immutability
  3. "6.005 — Software Construction".
  4. David O'Meara (April 2003). "Mutable and Immutable Objects: Make sure methods can't be overridden". Java Ranch. Retrieved 2012-05-14. The preferred way is to make the class final. This is sometimes referred to as "Strong Immutability". It prevents anyone from extending your class and accidentally or deliberately making it mutable.
  5. "Built-in Functions — Python v3.0 documentation". docs.python.org.
  6. 6.0 6.1 D भाषा विशिष्टता § 18
  7. D Language Specification § 12.16 (The terms array and slice are used interchangeably.)
  8. "How to create Immutable Class and Object in Java – Tutorial Example". Javarevisited.blogspot.co.uk. 2013-03-04. Retrieved 2014-04-14.
  9. "अपरिवर्तनीय वस्तुएं". javapractices.com. Retrieved November 15, 2012.
  10. "Immutability in JavaScript: A Contrarian View". Desalasworks.
  11. "Scala 2.8 Collections API – Concrete Immutable Collection Classes". Scala-lang.org. Retrieved 2014-04-14.


बाहरी संबंध