বানর প্যাচিং। আপনি যখন প্রথম রুবি চেষ্টা করেন, এটি আশ্চর্যজনক। আপনি মূল ক্লাসে সঠিক পদ্ধতি যোগ করতে পারেন! আপনাকে কল করতে হবে না Time.now.advance(days: -1)
, আপনি 1.day.ago
লিখতে পারেন ! এটি রুবিকে পড়তে এবং লিখতে আনন্দ দেয়। যতক্ষণ না…
আপনি অদ্ভুত বাগ আঘাত করেছেন কারণ একটি প্যাচ Hash
পরিবর্তিত হয়েছে .
আসলে কোন কোডটি চলেছিল তা নিয়ে আপনি বিভ্রান্ত হন, তাই এটি ভেঙে গেলে আপনি এটি ডিবাগ করতে পারবেন না।
এবং আপনি অবশেষে বুঝতে পেরেছিলেন যে আপনার সমস্ত সমস্যা ছয় মাস আগে হয়েছিল, যখন আপনি Enumerable
বানর-প্যাচ করেছিলেন কোডের একটি লাইনকে পাঁচটি অক্ষর ছোট করতে।
কিন্তু বিকল্প কি? আদৌ কোন সুবিধা নেই? কোড যা দেখতে GroupableArray.new([1, 2, 3, 4]).in_groups_of(2)
? blank?
এর জন্য অপেক্ষা করছেন আপনাকে সুন্দর ব্যবহারকারী ইনপুট হ্যান্ডলিং করার অনুমতি দেওয়ার আগে এটিকে মূল রুবিতে পরিণত করতে?
আপনি সম্পূর্ণরূপে বানর প্যাচ ছেড়ে দিতে চান না. কিন্তু আপনি কীভাবে বানরের প্যাচ লিখতে পারেন যেটি হবে না পরের বার যখন আপনি তাদের দেখতে চান তখন আপনি অযোগ্যতার জন্য নিজেকে বরখাস্ত করতে চান?
এগুলিকে একটি মডিউলে রাখুন
আপনি যখন বানর একটি ক্লাস প্যাচ করেন, তখন শুধু ক্লাসটি আবার খুলবেন না এবং আপনার প্যাচটি এতে ঢোকাবেন না:
class DateTime
def weekday?
!sunday? && !saturday?
end
end
কেন নয়?
-
যদি দুটি লাইব্রেরি একই পদ্ধতিতে বানর-প্যাচ করে, আপনি বলতে পারবেন না।
প্রথম বানর-প্যাচটি ওভাররাইট হয়ে চিরতরে অদৃশ্য হয়ে যাবে।
-
যদি কোনো ত্রুটি থাকে, তাহলে মনে হবে ত্রুটিটি
DateTime
এর মধ্যে ঘটেছে .যদিও টেকনিক্যালি সত্য, এটা তেমন সহায়ক নয়।
-
আপনার বানরের প্যাচগুলি বন্ধ করা আরও কঠিন৷৷
আপনাকে হয় আপনার সম্পূর্ণ প্যাচটি মন্তব্য করতে হবে, অথবা আপনি যদি এটি ছাড়া কোড চালাতে চান তবে আপনার বানর প্যাচ ফাইলের প্রয়োজনটি এড়িয়ে যান৷
-
যদি আপনি বলুন,
require 'date'
ভুলে গেছেন এই বানর প্যাচটি চালানোর আগে, আপনি ঘটনাক্রমে পুনরায় সংজ্ঞায়িত করবেনDateTime
এটি প্যাচ করার পরিবর্তে।
পরিবর্তে, আপনার বানরের প্যাচগুলি একটি মডিউলে রাখুন:
module CoreExtensions
module DateTime
module BusinessDays
def weekday?
!sunday? && !saturday?
end
end
end
end
এইভাবে, আপনি একসাথে সম্পর্কিত বানর প্যাচগুলি সংগঠিত করতে পারেন। যখন একটি ত্রুটি থাকে, তখন সমস্যা কোডটি কোথা থেকে এসেছে তা স্পষ্ট। এবং আপনি তাদের একবারে একটি গ্রুপ অন্তর্ভুক্ত করতে পারেন:
# Actually monkey-patch DateTime
DateTime.include CoreExtensions::DateTime::BusinessDays
আপনি যদি আর প্যাচটি না চান, শুধু সেই লাইনটি মন্তব্য করুন৷
৷এদের একসাথে রাখুন
আপনি যখন বানর প্যাচ কোর ক্লাস করেন, তখন আপনি মূল রুবি API-তে যোগ করেন। কোর প্যাচ সহ প্রতিটি অ্যাপ একটু আলাদা বোধ করে। সুতরাং আপনি যখন একটি নতুন কোডবেসে ঝাঁপ দেন তখন সেই পরিবর্তনগুলি দ্রুত শিখতে আপনার একটি উপায় থাকতে হবে৷ আপনার বানরের প্যাচগুলি কোথায় থাকে তা আপনাকে জানতে হবে।
আমি বেশিরভাগই রেলের বানর-প্যাচিং কনভেনশন অনুসরণ করি। প্যাচগুলি lib/core_extensions/class_name/group.rb
-এ যায় . তাই এই প্যাচ:
module CoreExtensions
module DateTime
module BusinessDays
def weekday?
!sunday? && !saturday?
end
end
end
end
lib/core_extensions/date_time/business_days.rb
-এ যাবে .
যেকোন নতুন বিকাশকারী lib/core_extensions
-এ রুবি ফাইলগুলি ব্রাউজ করতে পারে এবং আপনি রুবিতে কি যোগ করেছেন তা শিখুন। এবং তারা আসলে ব্যবহার করবে আপনি যে সুবিধাজনক নতুন পদ্ধতিগুলি লিখেছেন, সেই পদ্ধতিগুলির পরিবর্তে সেই পদ্ধতিগুলি কেবল পথে আসছে৷
প্রান্তের ক্ষেত্রে চিন্তা করুন
আমি জানি না কেন Enumerable
একটি sum
নেই পদ্ধতি তাই প্রায়ই, আমি [1, 2, 3].sum
লিখতে চাই , অথবা ["a", "b", "c"].sum
, অথবা [Article.new, Article.new, Article.new].sum
… ওহ।
আপনি যখন বানর একটি ক্লাস প্যাচ করেন, তখন আপনি সাধারণত এমন একটি জিনিস সম্পর্কে চিন্তা করেন যা আপনি সহজ করতে চান। আপনি সংখ্যার যোগফল গণনা করতে চান, কিন্তু ভুলে যান যে অ্যারে অন্যান্য জিনিস ধারণ করতে পারে।
এই মুহূর্তে, এটা জ্ঞান করে তোলে. আপনি একগুচ্ছ হ্যাশের গড় গণনা করার চেষ্টা করবেন না। কিন্তু আপনি যখন কোনো বস্তুর সাথে এমন পদ্ধতি সংযুক্ত করেন যেগুলোকে আপনি কখনো কখনো কল করার সময় ব্যর্থ হন, আপনি পরে নিজেকে বিভ্রান্ত করবেন।
আপনি কয়েকটি উপায়ে এটি মোকাবেলা করতে পারেন। সেরা থেকে খারাপ পর্যন্ত:
-
অপ্রত্যাশিত ইনপুট যুক্তিসঙ্গতভাবে পরিচালনা করুন।
আপনার প্যাচ স্ট্রিংগুলির সাথে কাজ করলে এটি ভাল কাজ করে। আপনি
to_s
কল করলে আপনি প্রায় যেকোনো কিছু থেকে যুক্তিসঙ্গত কিছু পেতে পারেন এটা প্রথম. এবং আত্মবিশ্বাসী রুবি আপনাকে বিভিন্ন ধরণের ইনপুট মোকাবেলা করার অনেক উপায় শেখাবে। -
একটি পরিষ্কার উপায়ে ত্রুটি পরিচালনা করুন৷৷
এটি একটি
ArgumentError
নিক্ষেপ করার মতোই সহজ হতে পারে একটি ভাল বার্তা সহ যখন আপনি ইনপুট দেখেন যে আপনি আশা করছেন না। র্যান্ডমNoMethodError
বোঝার উপর নির্ভর করবেন না s. -
একটি মন্তব্যে আপনি যে ধরনের ইনপুট আশা করেন তা নথিভুক্ত করুন৷৷
অন্য দুটি বিকল্প ভাল, যদি আপনি সেগুলি ব্যবহার করতে পারেন। তবে আপনি যদি আপনার প্যাচের ভিতরে প্রান্তের কেসগুলি পরীক্ষা করতে না পারেন তবে অন্তত সেগুলি নথিভুক্ত করুন। এইভাবে, একবার আপনার কলকারী বুঝতে পারবেন যে এটি আপনার প্যাচ যা তাদের সমস্যা সৃষ্টি করছে, আপনি কী করার চেষ্টা করছেন সে সম্পর্কে তাদের ধারণা থাকবে।
আমার সর্বকালের প্রিয় বানর প্যাচ
অবশেষে, আমি আপনাকে আমার সর্বকালের প্রিয় বানর প্যাচ দিয়ে যেতে চাই:Hash#string_merge
:
module CoreExtensions
module Hash
module Merging
def string_merge(other_hash, separator = " ")
merge(other_hash) {|key, old, new| old.to_s + separator + new.to_s}
end
end
end
end
{}.string_merge({:class => "btn"}) # => {:class=>"btn"}
h = {:class => "btn"} # => {:class=>"btn"}
h.string_merge({:class => "btn-primary"}) # => {:class=>"btn btn-primary"}
এটি HTML উপাদানের সাথে CSS ক্লাস সংযুক্ত করে তাই অনেক সুন্দর।
বুদ্ধিসম্পন্ন বানর প্যাচিং
বানর-প্যাচিং কোর ক্লাস সব খারাপ নয়। আপনি যখন এটি ভাল করেন, তখন এটি আপনার কোডকে রুবির মতো মনে করে। কিন্তু রুবির তীক্ষ্ণ প্রান্তগুলির মতোই, সেগুলি ব্যবহার করার সময় আপনাকে অতিরিক্ত যত্ন নিতে হবে৷
আপনি যদি আপনার প্যাচগুলিকে একত্রে রাখেন, সেগুলিকে মডিউলগুলিতে গোষ্ঠীবদ্ধ করেন এবং অপ্রত্যাশিতগুলি পরিচালনা করেন, আপনার বানরের প্যাচগুলি যতটা নিরাপদ হতে পারে।
সর্বোত্তম বানর প্যাচ কি আপনার আছে কখনও লেখা (বা দেখা)? একটি মন্তব্য করুন এবং এটি সম্পর্কে আমাকে বলুন!