Metaprogramming একটি খুব অভিনব শব্দ মত শোনাচ্ছে, কিন্তু এটা কোন ভাল?
এটি দরকারী হতে পারে, কিন্তু অনেক লোক বুঝতে পারে না যে মেটাপ্রোগ্রামিং ব্যবহার করার কিছু খরচ আছে৷
ঠিক তাই আমরা একই পৃষ্ঠায়…
মেটাপ্রোগ্রামিং কি ঠিক?
আমি মেটাপ্রোগ্রামিংকে সংজ্ঞায়িত করি যে কোনো পদ্ধতি ব্যবহার করে:
- আপনার কোডের গঠন পরিবর্তন করে (যেমন
define_method
) - একটি স্ট্রিং চালায় যেন এটি আপনার প্রকৃত রুবি কোডের অংশ (যেমন
instance_eval
) - কিছু ইভেন্টের প্রতিক্রিয়া হিসাবে কিছু করে (যেমন
method_missing
)
তাই মেটাপ্রোগ্রামিং খরচ কি? আমি তাদের 3টি গ্রুপে শ্রেণীবদ্ধ করি:
- গতি
- পঠনযোগ্যতা
- অনুসন্ধানযোগ্যতা
দ্রষ্টব্য :আপনি এটাও বলতে পারেন যে একটি চতুর্থ গ্রুপ আছে:নিরাপত্তা . এর কারণ হল
eval
পদ্ধতি, যা পাস করা হচ্ছে তার উপর কোনো ধরনের নিরাপত্তা পরীক্ষা করে না। আপনাকে তা করতে হবে।
আসুন সেগুলির প্রতিটিকে আরও বিস্তারিতভাবে অন্বেষণ করি!
গতি
প্রথম খরচ হল গতি কারণ বেশিরভাগ মেটাপ্রোগ্রামিং পদ্ধতি নিয়মিত পদ্ধতির চেয়ে ধীর।
এখানে কিছু বেঞ্চমার্কিং কোড আছে:
'benchmark/ips'class Thing def method_missing(name, *args) end def normal_method শেষ define_method(:speak) {}endt =Thing.newBenchmark.ips করতে হবে |x| x.report("সাধারণ পদ্ধতি") { t.normal_method } x.report("অনুপস্থিত পদ্ধতি") { t.abc } x.report("সংজ্ঞায়িত পদ্ধতি") { t.speak } x.compare!end
ফলাফল (রুবি 2.2.4) :
<প্রে>স্বাভাবিক পদ্ধতি:7344529.4 i/s নির্ধারিত পদ্ধতি:5766584.9 i/s - 1.34x ধীরগতির মিসিং পদ্ধতি:4777911.7 i/s - 1.54x ধীর
আপনি উভয় মেটাপ্রোগ্রামিং পদ্ধতি দেখতে পাচ্ছেন (define_method
&method_missing
) স্বাভাবিক পদ্ধতির তুলনায় বেশ কিছুটা ধীর।
এখানে আকর্ষণীয় কিছু আমি আবিষ্কার করেছি…
উপরের ফলাফলগুলি Ruby 2.2.4
থেকে , কিন্তু আপনি যদি এই বেঞ্চমার্কগুলি Ruby 2.3
এ চালান অথবা Ruby 2.4
দেখে মনে হচ্ছে এই পদ্ধতিগুলি ধীর হয়ে যাচ্ছে!
রুবি 2.4 বেঞ্চমার্ক ফলাফল :
স্বাভাবিক পদ্ধতি:8252851.6 i/s নির্ধারিত পদ্ধতি:6153202.9 i/s - 1.39x স্লোয়ার মিসিং পদ্ধতি:4557376.3 i/s - 1.87x ধীর
এটি একটি ফ্লুক নয় তা নিশ্চিত করতে আমি বেশ কয়েকবার এই বেঞ্চমার্কটি চালিয়েছি৷
৷
কিন্তু আপনি যদি মনোযোগ দেন এবং প্রতি সেকেন্ডে পুনরাবৃত্তির দিকে তাকান (i/s
) মনে হচ্ছে রুবি 2.3 থেকে নিয়মিত পদ্ধতিগুলি দ্রুত হয়ে গেছে। এটাই হল method_missing
অনেক ধীর দেখায় 🙂
পঠনযোগ্যতা
instance_eval
ব্যবহার করার সময় ত্রুটির বার্তা কম সহায়ক হতে পারে / class_eval
পদ্ধতি।
নিম্নলিখিত কোডটি দেখুন:
class Thing class_eval("def self.foo; raise 'something wrong'; end")endThing.foo
এর ফলে নিম্নলিখিত ত্রুটি হবে:
(eval):1:in 'foo':'কিছু ভুল হয়েছে...' (RuntimeError)
লক্ষ্য করুন যে আমরা ফাইলের নামটি হারিয়ে ফেলছি (এটি eval
বলে পরিবর্তে) এবং সঠিক লাইন নম্বর। ভাল খবর হল এর জন্য একটি সমাধান আছে, এই eval
পদ্ধতি দুটি অতিরিক্ত প্যারামিটার নেয়:
- একটি ফাইলের নাম
- একটি লাইন নম্বর
অন্তর্নির্মিত ধ্রুবক __FILE__
ব্যবহার করে &__LINE__
class_eval
-এর প্যারামিটার হিসাবে আপনি ত্রুটি বার্তায় সঠিক তথ্য পাবেন।
উদাহরণ :
class Thing class_eval( "def foo; raise 'something went right'; end", __FILE__, __LINE__ )end
কেন এটি ডিফল্ট নয়?
আমি জানি না, তবে আপনি যদি এই পদ্ধতিগুলি ব্যবহার করতে যাচ্ছেন তবে এটি মনে রাখতে হবে 🙂
অনুসন্ধানযোগ্যতা
মেটাপ্রোগ্রামিং পদ্ধতিগুলি আপনার কোডকে কম অনুসন্ধানযোগ্য, কম অ্যাক্সেসযোগ্য (খারাপ ডকুমেন্টেশনের মাধ্যমে) এবং ডিবাগ করা কঠিন করে তোলে৷
আপনি যদি একটি পদ্ধতির সংজ্ঞা খুঁজছেন তবে আপনি মেটাপ্রোগ্রামিংয়ের মাধ্যমে সংজ্ঞায়িত একটি পদ্ধতি খুঁজে পেতে CTRL+F (অথবা আপনি যে কোনো শর্টকাট ব্যবহার করুন) করতে পারবেন না, বিশেষ করে যদি পদ্ধতিটির নাম রান-টাইমে তৈরি করা হয়।
নিম্নলিখিত উদাহরণ 3টি পদ্ধতি সংজ্ঞায়িত করে৷ মেটাপ্রোগ্রামিং ব্যবহার করে:
class RubyBlog def create_post_tags type =['computer_science', 'tools', 'advanced_ruby'] type.each do |type| define_singleton_method(type + "_tag") { রাখে "এই পোস্টটি #{type}" } } endendrb =RubyBlog.newrb.create_post_tagsrb.computer_science_tag
টুল যা ডকুমেন্টেশন তৈরি করে (যেমন Yard
অথবা RDoc
) এই পদ্ধতিগুলি খুঁজে পেতে এবং তাদের তালিকা করতে পারে না৷
এই সরঞ্জামগুলি ক্লাস এবং পদ্ধতিগুলি খুঁজে পেতে "স্ট্যাটিক বিশ্লেষণ" নামে একটি কৌশল ব্যবহার করে। এই কৌশলটি শুধুমাত্র সরাসরি সংজ্ঞায়িত পদ্ধতিগুলি খুঁজে পেতে পারে (def
ব্যবহার করে সিনট্যাক্স)।
yard doc
চালানোর চেষ্টা করুন শেষ উদাহরণ দিয়ে, আপনি দেখতে পাবেন যে একমাত্র পদ্ধতিটি হল create_post_tags
.
এটা এরকম দেখাচ্ছে :
Yard
বলার একটি উপায় আছে @method
ব্যবহার করে অতিরিক্ত পদ্ধতি নথিভুক্ত করতে ট্যাগ, কিন্তু এটা সবসময় ব্যবহারিক হয় না।
উদাহরণ :
শ্রেণীর জিনিস # @method build_report define_method(:build_report)end
এছাড়াও আপনি যদি grep
এর মত একটি টুল ব্যবহার করতে যাচ্ছেন , ack
, অথবা পদ্ধতির সংজ্ঞা অনুসন্ধান করার জন্য আপনার সম্পাদক, মেটাপ্রোগ্রামিং পদ্ধতিগুলি খুঁজে পাওয়া কঠিন হতে চলেছে নিয়মিত পদ্ধতির চেয়ে।
“আমি মনে করি না Sidekiq কোনো মেটাপ্রোগ্রামিং ব্যবহার করে মোটেও কারণ আমি দেখতে পাই যে এটি 95% সময় সাহায্য করে তার চেয়ে বেশি কোডটিকে অস্পষ্ট করে।" - মাইক পারহাম, সিডেকিকের স্রষ্টা
উপসংহার
মেটাপ্রোগ্রামিং সম্পর্কে সবকিছু খারাপ নয়। আপনার কোডটিকে আরও নমনীয় করতে সঠিক পরিস্থিতিতে এটি কার্যকর হতে পারে৷
শুধু অতিরিক্ত খরচ সম্পর্কে সচেতন থাকুন যাতে আপনি আরও ভালো সিদ্ধান্ত নিতে পারেন।
এই পোস্টটি শেয়ার করতে ভুলবেন না যদি আপনি এটি দরকারী খুঁজে পান 🙂