class MyClass
def mymethod
MYCONSTANT = "blah"
end
end
আমাকে ত্রুটি দেয়:
সিনট্যাক্সেরর: গতিশীল ধ্রুবক অ্যাসাইনমেন্ট ত্রুটি
এটিকে কেন গতিশীল ধ্রুবক হিসাবে বিবেচনা করা হয়? আমি এটিতে একটি স্ট্রিং বরাদ্দ করছি।
class MyClass
def mymethod
MYCONSTANT = "blah"
end
end
আমাকে ত্রুটি দেয়:
সিনট্যাক্সেরর: গতিশীল ধ্রুবক অ্যাসাইনমেন্ট ত্রুটি
এটিকে কেন গতিশীল ধ্রুবক হিসাবে বিবেচনা করা হয়? আমি এটিতে একটি স্ট্রিং বরাদ্দ করছি।
উত্তর:
আপনার সমস্যাটি হ'ল প্রতিবার আপনি যে পদ্ধতিটি চালাচ্ছেন আপনি ধ্রুবকে একটি নতুন মান নির্ধারণ করছেন। এটি অনুমোদিত নয়, কারণ এটি ধ্রুবকটিকে অ-ধ্রুব করে তোলে; যদিও স্ট্রিংয়ের বিষয়বস্তু একই (মুহূর্তের জন্য, যে কোনওভাবে) একই হলেও, প্রতিটি বার পদ্ধতিটি বলা হওয়ার পরে প্রকৃত স্ট্রিং অবজেক্ট নিজেই আলাদা হয়। উদাহরণ স্বরূপ:
def foo
p "bar".object_id
end
foo #=> 15779172
foo #=> 15779112
সম্ভবত আপনি যদি আপনার ব্যবহারের কেস ব্যাখ্যা করেন - আপনি কেন কোনও পদ্ধতিতে ধ্রুবকের মান পরিবর্তন করতে চান — আমরা আপনাকে আরও ভাল বাস্তবায়নে সহায়তা করতে পারি।
সম্ভবত আপনি বরং ক্লাসে একটি উদাহরণ পরিবর্তনশীল আছে?
class MyClass
class << self
attr_accessor :my_constant
end
def my_method
self.class.my_constant = "blah"
end
end
p MyClass.my_constant #=> nil
MyClass.new.my_method
p MyClass.my_constant #=> "blah"
আপনি যদি কোনও পদ্ধতিতে ধ্রুবকের মানটি সত্যিই পরিবর্তন করতে চান এবং আপনার ধ্রুবকটি স্ট্রিং বা অ্যারে হয় তবে আপনি আসলে 'প্রতারণা' করতে পারেন এবং #replace
অবজেক্টটি আসলে পরিবর্তন না করেই কোনও নতুন মান গ্রহণের জন্য এই পদ্ধতিটি ব্যবহার করতে পারেন:
class MyClass
BAR = "blah"
def cheat(new_bar)
BAR.replace new_bar
end
end
p MyClass::BAR #=> "blah"
MyClass.new.cheat "whee"
p MyClass::BAR #=> "whee"
def initialize(db,user,password) DB=Sequel.connect("postgres://#{user}:#{password}@localhost/#{db}") end
। এটি এমন একটি ক্ষেত্রে যেখানে রুবির কোনও সহজ উপায় নেই।
@variable
একটি ধ্রুবক নয়, উদাহরণস্বরূপ পরিবর্তনশীল (যেমন ) চান । অন্যথায় আপনি DB
যখনই এই শ্রেণীর কোনও নতুন উদাহরণ ইনস্ট্যান্ট করলেন প্রতিবার আপনাকে পুনরায় বরাদ্দ দেওয়া হবে ।
Sequel.connect
স্থির নামযুক্ত ডিবিতে ফলাফল নির্ধারণের জন্য থাকতে পারেন । প্রকৃতপক্ষে, ডকুমেন্টেশনগুলি পরিষ্কারভাবে বলেছে যে এটি কেবল একটি সুপারিশ। এটি আমার কাছে বাহ্যিক প্রতিবন্ধকতার মতো শোনাচ্ছে না।
যেহেতু রুবির স্থির পরিবর্তনগুলি বোঝানো হচ্ছে না, রুবি আপনাকে কোডের কিছু অংশে তাদের অর্পণ করতে নিরুৎসাহিত করে যা অভ্যন্তরীণ পদ্ধতির মতো একাধিকবার কার্যকর করা হতে পারে।
সাধারণ পরিস্থিতিতে আপনার নিজের ক্লাসের ভিতরেই ধ্রুবকটি সংজ্ঞায়িত করা উচিত:
class MyClass
MY_CONSTANT = "foo"
end
MyClass::MY_CONSTANT #=> "foo"
যদি কোনও কারণে আপনাকে কোনও পদ্ধতির অভ্যন্তরে ধ্রুবক সংজ্ঞায়িত করার প্রয়োজন হয় (সম্ভবত কোনও ধরণের রূপক ব্যবহারের জন্য), আপনি ব্যবহার করতে পারেন const_set
:
class MyClass
def my_method
self.class.const_set(:MY_CONSTANT, "foo")
end
end
MyClass::MY_CONSTANT
#=> NameError: uninitialized constant MyClass::MY_CONSTANT
MyClass.new.my_method
MyClass::MY_CONSTANT #=> "foo"
আবার যদিও, const_set
সাধারণ পরিস্থিতিতে আপনাকে সত্যই অবলম্বন করা উচিত নয়। আপনি যদি সত্যিই এইভাবে ধ্রুবককে অর্পণ করতে চান কিনা তা নিশ্চিত না হন তবে আপনি নিম্নলিখিত বিকল্পগুলির মধ্যে একটি বিবেচনা করতে পারেন:
শ্রেণি ভেরিয়েবলগুলি বিভিন্ন উপায়ে ধ্রুবকের মতো আচরণ করে। এগুলি কোনও শ্রেণীর বৈশিষ্ট্য এবং এগুলি যে শ্রেণীর উপর সংজ্ঞায়িত করা হয়েছে সেগুলির সাবক্লাসে সেগুলি অ্যাক্সেসযোগ্য।
পার্থক্যটি হ'ল শ্রেণি ভেরিয়েবলগুলি সংশোধনযোগ্য বলে বোঝানো হয় এবং তাই কোনও সমস্যা ছাড়াই অভ্যন্তরীণ পদ্ধতিতে নির্ধারিত হতে পারে।
class MyClass
def self.my_class_variable
@@my_class_variable
end
def my_method
@@my_class_variable = "foo"
end
end
class SubClass < MyClass
end
MyClass.my_class_variable
#=> NameError: uninitialized class variable @@my_class_variable in MyClass
SubClass.my_class_variable
#=> NameError: uninitialized class variable @@my_class_variable in MyClass
MyClass.new.my_method
MyClass.my_class_variable #=> "foo"
SubClass.my_class_variable #=> "foo"
শ্রেণীর বৈশিষ্ট্যগুলি হ'ল "শ্রেণীর উপর উদাহরণ পরিবর্তনশীল" of তারা ক্লাস ভেরিয়েবলগুলির মতো কিছুটা আচরণ করে, তাদের মানগুলি সাবক্লাসের সাথে ভাগ না করা ব্যতীত।
class MyClass
class << self
attr_accessor :my_class_attribute
end
def my_method
self.class.my_class_attribute = "blah"
end
end
class SubClass < MyClass
end
MyClass.my_class_attribute #=> nil
SubClass.my_class_attribute #=> nil
MyClass.new.my_method
MyClass.my_class_attribute #=> "blah"
SubClass.my_class_attribute #=> nil
SubClass.new.my_method
SubClass.my_class_attribute #=> "blah"
এবং কেবল সম্পূর্ণতার জন্য আমার সম্ভবত উল্লেখ করা উচিত: আপনার শ্রেণিটি তাত্ক্ষণিকভাবে চালিত হওয়ার পরে যদি আপনাকে কোনও মূল্য নির্ধারণ করা প্রয়োজন তবে আপনি সম্ভবত একটি সাধারণ পুরানো উদাহরণের পরিবর্তনশীল খুঁজছেন এমন একটি ভাল সুযোগ রয়েছে।
class MyClass
attr_accessor :instance_variable
def my_method
@instance_variable = "blah"
end
end
my_object = MyClass.new
my_object.instance_variable #=> nil
my_object.my_method
my_object.instance_variable #=> "blah"
MyClass.new.instance_variable #=> nil
রুবিতে, কোনও পরিবর্তনশীল যার নাম মূলধনির সাথে শুরু হয় এটি একটি ধ্রুবক এবং আপনি কেবল একবার এটি বরাদ্দ করতে পারেন। এই বিকল্পগুলির মধ্যে একটি চয়ন করুন:
class MyClass
MYCONSTANT = "blah"
def mymethod
MYCONSTANT
end
end
class MyClass
def mymethod
my_constant = "blah"
end
end
রুবিতে থাকা ধ্রুবকগুলি অভ্যন্তরীণ পদ্ধতিগুলির মধ্যে সংজ্ঞায়িত করা যায় না। উদাহরণস্বরূপ, এই পৃষ্ঠার নীচে নোটগুলি দেখুন
আপনি মূল অক্ষরের সাথে কোনও ভেরিয়েবলের নাম রাখতে পারবেন না বা রুবি এটির একটি ধ্রুবক হিসাবে বিবেচিত হবে এবং এটির মান স্থিতিশীল রাখতে চাইবে, সেই ক্ষেত্রে এর মান পরিবর্তন করা একটি "গতিশীল ধ্রুবক অ্যাসাইনমেন্ট ত্রুটি" হতে পারে। লোয়ার কেস দিয়ে জরিমানা করা উচিত
class MyClass
def mymethod
myconstant = "blah"
end
end
রুবি পছন্দ করেন না যে আপনি কোনও পদ্ধতির অভ্যন্তরে ধ্রুবক বরাদ্দ করছেন কারণ এটি পুনরায় নিয়োগের ঝুঁকি নিয়েছে। আমার আগে বেশ কয়েকটি এসও উত্তর একটি পদ্ধতির বাইরে এটি নির্ধারণের বিকল্পটি দেয় - তবে ক্লাসে, এটি নির্ধারণের জন্য আরও ভাল জায়গা।
অ্যারে (এবং হ্যাশ) পদ্ধতি # স্থান সম্পর্কে আমাকে স্মরণ করিয়ে দেওয়ার জন্য ডোরিয়ান এবং ফ্রোগজকে অনেক ধন্যবাদ, যা "অ্যারে বা হ্যাশের সামগ্রীগুলি প্রতিস্থাপন করতে পারে"।
একটি কনস্ট্যান্টের মান পরিবর্তিত হতে পারে এমন ধারণা, কিন্তু একটি বিরক্তিকর সতর্কতা সহ, রুবির কয়েকটি ধারণামূলক ভুল পদক্ষেপগুলির মধ্যে একটি - এটি হয় সম্পূর্ণরূপে অপরিবর্তনীয় বা স্থির ধারণাটিকে পুরোপুরি ফেলে দিতে হবে dump কোডারের দৃষ্টিকোণ থেকে, একটি ধ্রুবকটি ঘোষণামূলক এবং ইচ্ছাকৃত, এটি অন্যের কাছে একটি সংকেত যে "এই মানটি সত্যই একবার ঘোষিত / নির্ধারিত হয়ে গেলে তা পরিবর্তনযোগ্য" "
তবে কখনও কখনও একটি "সুস্পষ্ট ঘোষণা" আসলে ভবিষ্যতের অন্যান্য কার্যকর সুযোগগুলিকে পূর্বাভাস দেয়। উদাহরণ স্বরূপ...
সেখানে হয় উদাহরণস্বরূপ, একটি REPL মত প্রম্পট-লুপ থেকে পুনরায় লোড argv, তারপর পুরনো আরো (পরবর্তী) OptionParser.parse argv rerunning: বৈধ ব্যবহারের ক্ষেত্রে যেখানে একটি "ধ্রুবক এর" মান সত্যিই পরিবর্তন করা প্রয়োজন হতে পারে! কল - ভয়েলা! "কমান্ড লাইন আরগস" একটি সম্পূর্ণ নতুন গতিশীল ইউটিলিটি দেয়।
ব্যবহারিক সমস্যা পারেন সম্ভাব্য ধৃষ্টতা যে, "argv একটি ধ্রুবক হতে হবে" সঙ্গে বা optparse নিজস্ব আরম্ভ পদ্ধতিতে, যা হার্ড কোড পরবর্তী প্রক্রিয়াকরণের জন্য উদাহরণস্বরূপ Var @default_argv করার argv এর নিয়োগ - যে অ্যারে (argv) সত্যিই প্যারামিটার হওয়া উচিত, পুনর্-পার্স এবং পুনরায় ব্যবহারকে উত্সাহিত করা, যেখানে উপযুক্ত। উপযুক্ত প্যারামিটারাইজেশন, উপযুক্ত ডিফল্ট (বলুন, এআরজিভি) কখনও "ধ্রুবক" এআরজিভি পরিবর্তন করার প্রয়োজন এড়াতে পারে। চিন্তাভাবনার মাত্র 2 wor-ওয়ার্থ ...