কম্পিউটার

রুবি পরিমার্জন এবং আভিধানিক সুযোগ বোঝা

আপনি যদি আগে কখনও পরিমার্জন ব্যবহার না করেন, তাহলে আপনি সম্ভবত একটি আশ্চর্যের জন্য আছেন। আপনি হয়তো শুনেছেন যে বানর প্যাচিং প্রতিস্থাপনের জন্য পরিমার্জন চালু করা হয়েছিল। তাই আপনি আশা করতে পারেন যে আপনি ActiveSupport এর hours এর মত কিছু বাস্তবায়ন করতে সক্ষম হবেন পদ্ধতি:

module TimeExtension
  refine Fixnum do
    def hours
      self * 60
    end
  end
end

class MyFramework
  using TimeExtension
end

class MyApp < MyFramework
  def index
    1.hours
  end
end

MyApp.new.index # undefined method `hours' for 1:Fixnum (NoMethodError)

আপনি যদি উপরের কোডটি চালাতে চান তবে আপনি দেখতে পাবেন যে এটি কাজ করে না। তাই কি দেয়?

অন্যান্য অনেক দুর্দান্ত ধারণার মতো, পরিমার্জনার মূল ধারণাটিকে কঠিন বাস্তবতার সাথে কাজ করার জন্য পরিবর্তন করতে হয়েছিল৷

কোডের আশ্চর্যজনক আচরণ যা আমরা উপরে দেখেছি তা এই পরিবর্তনগুলির একটির কারণে ঘটে। বিশেষত, নিয়ম যা বলে যে পরিমার্জনগুলি আভিধানিকভাবে ব্যাপ্ত।

লেক্সিকাল স্কোপিং কি?

যখন আমরা বলি যে কোনো কিছু আভিধানিক, তার মানে টেক্সট এর সাথে সম্পর্কযুক্ত - সেই কোডের অর্থের বিপরীতে স্ক্রীনের কোড।

যদি দুটি লাইন আভিধানিকভাবে স্কোপ করা হয়, তাহলে এর সহজ অর্থ হল যে সেগুলি একই কোড ব্লকের মধ্যে ঘটে — সেই কোড ব্লকের মূল্যায়ন যাই হোক না কেন।

এটি সম্পর্কে কথা বলার চেয়ে একটি উদাহরণ দেখা অনেক সহজ:

class B
  # x and y share the same lexical scope
  x = 1
  y = 1
end

class B
  # z has a different lexical scope from x and y, even though it's in the same class. 
  z = 3
end

পরিমার্জনগুলি আভিধানিকভাবে স্কোপ করা হয়

যখন আমরা কীওয়ার্ড ব্যবহার করে একটি পরিমার্জন প্রয়োগ করি, তখন পরিমার্জনটি শুধুমাত্র আভিধানিক সুযোগের মধ্যেই দৃশ্যমান হয়৷

আমি কি বলতে চাইছি তা এখানে একটি উদাহরণ রয়েছে:

module TimeExtension
  refine Fixnum do
    def hours
      self * 60
    end
  end
end

class MyApp
  using TimeExtension
  def index
    1.hours
  end
end

class MyApp
  def show
    2.hours
  end
end

MyApp.new.show # undefined method `hour' for 1:Fixnum (NoMethodError)

যদিও উভয়ই index এবং show পদ্ধতিগুলি একই শ্রেণীর অংশ, শুধুমাত্র index পদ্ধতিটির পরিমার্জনে অ্যাক্সেস রয়েছে, কারণ এটি শুধুমাত্র using এর সাথে আভিধানিক সুযোগ ভাগ করে বিবৃতি।

এটি সম্ভবত কিছুটা অদ্ভুত বলে মনে হচ্ছে, কারণ রুবিতে বাকি সবকিছুই গতিশীলভাবে স্কোপড। আপনি যখন একটি ক্লাসে একটি পদ্ধতি যোগ করেন, আপনি ক্লাস সংজ্ঞা থেকে প্রস্থান করলে পদ্ধতিটি সেখানেই থাকে। কিন্তু পরিমার্জনগুলি এভাবে কাজ করে না৷

এটি এমন অনেকগুলি পরিণতি যা প্রথমে স্পষ্ট নাও হতে পারে৷

আপনি গতিশীলভাবে পরিমার্জন পদ্ধতি চালু করতে পারবেন না

কারণ send পদ্ধতিটি একই কোড ব্লকের মধ্যে সংজ্ঞায়িত করা হয় না যাতে আপনার ব্যবহারের বিবৃতি রয়েছে, এটি পরিমার্জন দেখতে পারে না৷

তাই এটি কাজ করে না:

class MyApp
  using TimeExtension
  def index
    1.send(:hours)
  end
end

আপনি পরিমার্জন পদ্ধতির অস্তিত্ব সম্পর্কে প্রশ্ন করতে পারবেন না

respond_to? পদ্ধতি একই কোড ব্লকের মধ্যে নয়। তাই এটি send একই কারণে কাজ করে না পদ্ধতি করে না।

class MyApp
  using TimeExtension
  def index
    1.respond_to?(:hours)
  end
end

উপসংহার

আমি আশা করি এটি কিছু বিভ্রান্তি দূর করবে যা আমি দেখেছি যে লোকেদের পরিমার্জনা রয়েছে। এগুলি অবশ্যই রুবির একটি সম্ভাব্য উপযোগী বৈশিষ্ট্য, তবে আপনি যদি সেগুলি আগে কখনও ব্যবহার না করেন তবে সেগুলি কিছুটা জটিল হতে পারে৷


  1. রুবি অবজেক্ট মডেল গভীরভাবে বোঝা

  2. কিভাবে Rbenv, RubyGems এবং Bundler একসাথে কাজ করে তা বোঝা

  3. রুবিতে সন্নিবেশ বাছাই বোঝা

  4. রুবি ফ্রিজ পদ্ধতি - বস্তুর পরিবর্তনশীলতা বোঝা