কেন রুবির অ্যাটর্_অ্যাকসেসর, অ্যাট্রি_ রিডার এবং অ্যাট্রি_রাইটার ব্যবহার করবেন?


517

রুবির কাছে কীগুলি ব্যবহার করে উদাহরণের ভেরিয়েবলগুলি ভাগ করে নেওয়ার এই সহজ ও সুবিধাজনক উপায় রয়েছে

attr_accessor :var
attr_reader :var
attr_writer :var

আমি কেন বেছে নেব attr_readerবা attr_writerযদি আমি কেবল ব্যবহার করতে attr_accessorপারি? পারফরম্যান্সের মতো কিছু আছে (যা আমি সন্দেহ করি)? আমার মনে হয় এর একটা কারণ আছে, নাহলে তারা এ জাতীয় চাবি তৈরি করত না।


উত্তর:


746

আপনার কোডটি পড়ার সাথে কারও কাছে আপনার অভিপ্রায়টি যোগাযোগ করতে আপনি বিভিন্ন অ্যাক্সেসর ব্যবহার করতে পারেন এবং ক্লাসগুলি লিখতে আরও সহজ করে তুলতে পারেন যা তাদের পাবলিক এপিআই বলা যাই হোক না কেন সঠিকভাবে কাজ করবে।

class Person
  attr_accessor :age
  ...
end

এখানে, আমি দেখতে পাচ্ছি যে আমি উভয়ই বয়স পড়তে এবং লিখতে পারি।

class Person
  attr_reader :age
  ...
end

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

কিন্তু পর্দার আড়ালে কী ঘটছে?

আপনি যদি লিখেন:

attr_writer :age

এটি অনুবাদ করা হয়:

def age=(value)
  @age = value
end

আপনি যদি লিখেন:

attr_reader :age

এটি অনুবাদ করা হয়:

def age
  @age
end

আপনি যদি লিখেন:

attr_accessor :age

এটি অনুবাদ করা হয়:

def age=(value)
  @age = value
end

def age
  @age
end

এটি জানার জন্য, এখানে অন্যভাবে চিন্তা করার উপায় রয়েছে: যদি আপনার কাছে অ্যাটর্নি _... সহায়তাকারী না থাকে এবং নিজেই অ্যাকসেসরগুলি লিখতে হয়, আপনি কি আপনার শ্রেণীর প্রয়োজনের চেয়ে আরও কোনও এক্সেসর লিখবেন? উদাহরণস্বরূপ, বয়স যদি কেবল পড়ার প্রয়োজন হয়, আপনি কি কোনও পদ্ধতি এটি লেখার অনুমতি দিয়ে লিখবেন?


53
বনাম confreaks.net/videos/… লেখার জন্য একটি উল্লেখযোগ্য পারফরম্যান্স সুবিধা রয়েছেattr_reader :adef a; return a; end
নাইট্রোডিস্ট

83
@ নাইট্রোডিস্ট, আকর্ষণীয়। রুবি ১.৮. For-এর জন্য, attr_readerসংজ্ঞায়িত অ্যাক্সেসরটি ম্যানুয়ালি সংজ্ঞায়িত অ্যাক্সেসর করে of 86% সময় নেয়। রুবি ১.৯.০ এর জন্য, attr_readerসংজ্ঞায়িত অ্যাক্সেসর ম্যানুয়ালি সংজ্ঞায়িত অ্যাক্সেসর করে এমন সময়ের 94% সময় নেয়। আমার সমস্ত পরীক্ষায়, অ্যাকসেসরগুলি দ্রুত: একটি অ্যাক্সেসর প্রায় 820 ন্যানোসেকেন্ড (রুবি 1.8.7) বা 440 ন্যানোসেকেন্ড (রুবি 1.9) লাগে। এই গতিতে, attr_accessorসামগ্রিক রানটাইমকে এক সেকেন্ডেরও বেশি উন্নতি করতে পারফরম্যান্স বেনিফিটের জন্য আপনাকে কয়েকশ মিলিয়ন বার কল করতে হবে ।
ওয়েন কনরাড

22
"সম্ভবত, এটি এই শ্রেণীর নির্মাতা দ্বারা সেট করা হয়েছে এবং স্থির থাকে।" এটি সঠিক নয়। পাঠকদের সাথে ইনস্ট্যান্স ভেরিয়েবলগুলি প্রায়শই পরিবর্তন হতে পারে। তবে এটি উদ্দেশ্যযুক্ত যে তাদের মানগুলি কেবল শ্রেণীর দ্বারা ব্যক্তিগতভাবে পরিবর্তিত হবে।
mlibby

11
আপনি 2 টিরও বেশি বৈশিষ্ট্য যুক্ত করতে "," ব্যবহার করতে পারেন, যেমন:attr_accessor :a, :b
অ্যান্ড্রু_1510

2
এই সমস্ত বছর পরে কি মূল্য জন্য: github.com/JuanitoFatas/… রুবি উপর সর্বশেষ মানদণ্ড অনুযায়ী 2.2.0 অ্যাট্রি_ * গেটার্স এবং সেটটারদের চেয়ে দ্রুততর are
মোল্লি

25

উপরের সমস্ত উত্তর সঠিক; attr_readerএবং attr_writerলেখার জন্য আরও স্বাচ্ছন্দ্যযুক্ত ম্যানুয়ালি যে পদ্ধতিগুলির জন্য তারা শর্টহ্যান্ডস সেগুলি টাইপ করুন। এগুলি ছাড়াও তারা নিজেরাই পদ্ধতি সংজ্ঞাটি লেখার চেয়ে আরও ভাল পারফরম্যান্স সরবরাহ করে। আরও তথ্যের জন্য অ্যারন প্যাটারসনের এই টক ( পিডিএফ ) থেকে 152 স্লাইডটি দেখুন ।


16

কোনও সামগ্রীর সমস্ত বৈশিষ্ট্যগুলি শ্রেণীর বাইরে থেকে সরাসরি সেট করে বোঝানো হয় না। আপনার সমস্ত দৃষ্টান্তের ভেরিয়েবলের জন্য লেখক থাকা সাধারণত দুর্বল এনক্যাপসুলেশনের লক্ষণ এবং একটি সতর্কতা যে আপনি আপনার ক্লাসগুলির মধ্যে খুব বেশি সংযোগ স্থাপন করছেন।

ব্যবহারিক উদাহরণ হিসাবে: আমি একটি ডিজাইন প্রোগ্রাম লিখেছিলাম যেখানে আপনি ধারকগুলির ভিতরে আইটেম রেখেছেন। আইটেমটি ছিল attr_reader :container, তবে কোনও লেখককে অফার করা অর্থহীন নয়, যেহেতু আইটেমটির ধারকটি পরিবর্তন করা উচিত কেবল তখনই এটি কোনও নতুন স্থানে রাখা হয়, যার জন্য অবস্থান সম্পর্কিত তথ্যও প্রয়োজন।


16

এটি বুঝতে গুরুত্বপূর্ণ যে অ্যাক্সেসররা ভেরিয়েবলের অ্যাক্সেসকে সীমাবদ্ধ করে, তবে তাদের সামগ্রীতে নয়। রুবিতে, অন্য কয়েকটি ওও ভাষার মতো, প্রতিটি চলক উদাহরণের জন্য একটি পয়েন্টার। সুতরাং আপনার যদি কোনও হ্যাশের কোনও বৈশিষ্ট্য রয়েছে, উদাহরণস্বরূপ, এবং আপনি এটিকে "কেবলমাত্র পঠনযোগ্য" হিসাবে সেট করেছেন আপনি সর্বদা এর সামগ্রী পরিবর্তন করতে পারবেন, তবে পয়েন্টারের সামগ্রী নয়। এটা দেখ:

irb(main):024:0> class A
irb(main):025:1> attr_reader :a
irb(main):026:1> def initialize
irb(main):027:2> @a = {a:1, b:2}
irb(main):028:2> end
irb(main):029:1> end
=> :initialize
irb(main):030:0> a = A.new
=> #<A:0x007ffc5a10fe88 @a={:a=>1, :b=>2}>
irb(main):031:0> a.a
=> {:a=>1, :b=>2}
irb(main):032:0> a.a.delete(:b)
=> 2
irb(main):033:0> a.a
=> {:a=>1}
irb(main):034:0> a.a = {}
NoMethodError: undefined method `a=' for #<A:0x007ffc5a10fe88 @a={:a=>1}>
        from (irb):34
        from /usr/local/bin/irb:11:in `<main>'

আপনি দেখতে পাচ্ছেন হ্যাশ @ এ থেকে একটি কী / মান জুটি মুছে ফেলা সম্ভব, যেমন নতুন কী যুক্ত করুন, মান পরিবর্তন করুন, এক্সেসেটর। তবে আপনি কোনও নতুন অবজেক্টের দিকে ইঙ্গিত করতে পারবেন না কারণ কেবল পঠনযোগ্য উদাহরণের পরিবর্তনশীল।


13

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

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