কম্পিউটার

রুবিতে চেকিং টাইপ করুন — ইয়ো সেলফ নষ্ট করার আগে ইয়ো সেলফ চেক করুন

চলুন এই পোস্টটি শুরু করা যাক একটি মজার ছোট অনুমান করার খেলা দিয়ে:আপনি কি মনে করেন রুবি অ্যাপ্লিকেশনে AppSignal দ্বারা ট্র্যাক করা সবচেয়ে সাধারণ ত্রুটিটি কী?

এটা অনুমান করা ন্যায্য যে আপনার মধ্যে অনেকেই এই প্রশ্নের উত্তর NoMethodError দিয়ে দিয়েছেন , একটি ব্যতিক্রম যা একটি বস্তুর একটি অস্তিত্বহীন পদ্ধতি কল করার কারণে ঘটে। মাঝে মাঝে, এটি পদ্ধতির নামের একটি টাইপোর কারণে হতে পারে, তবে প্রায়শই এটি ভুল ধরণের একটি বস্তুতে একটি পদ্ধতি কল করার ফলাফল, যা প্রায়শই একটি অপ্রত্যাশিত nil হতে পারে . এই ধরনের ত্রুটির ফ্রিকোয়েন্সি কমাতে রুবি ডেভেলপার হিসেবে আমরা কি কিছু করতে পারি?

উদ্ধার করার ধরন?

টেক্সট এডিটর বা প্রোগ্রামিং ল্যাঙ্গুয়েজ বাছাই ছাড়া, কিছু বিষয় টাইপ সিস্টেমের আলোচনার চেয়ে দ্রুত উত্তপ্ত বিতর্কে পরিণত হতে পারে। আমাদের এখানে বিস্তারিত জানার জন্য সময় নেই, কিন্তু ক্রিস স্মিথের পোস্ট "কি জানার আগে ডিবেটিং টাইপ সিস্টেমস" একটি চমৎকার কাজ করে।

বিস্তৃত পরিভাষায়, টাইপ সিস্টেম দুটি প্রধান বিভাগে বিভক্ত করা যেতে পারে - স্থির এবং গতিশীল। যদিও আগেরটি সময়ের আগে ঘটে (হয় কম্পাইলার বা একটি পৃথক টুলের মাধ্যমে), রানটাইমের সময় গতিশীল টাইপ চেকিং ঘটে, যেখানে প্রকৃত প্রকারগুলি বিকাশকারীর প্রত্যাশার সাথে সামঞ্জস্যপূর্ণ না হলে এটি ব্যতিক্রম হতে পারে৷

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

হাঁস টাইপিং

রুবি নিজেই একটি গতিশীল টাইপ-চেক করা ভাষা এবং একটি "ডাক টাইপিং" পদ্ধতি অনুসরণ করে:

যদি এটি হাঁসের মতো হাঁটে এবং হাঁসের মতো কাঁপতে থাকে, তবে এটি অবশ্যই হাঁস হবে।

এর মানে হল যে রুবি ডেভেলপাররা সাধারণত একটি বস্তুর ধরন নিয়ে খুব বেশি চিন্তা করেন না, তবে এটি নির্দিষ্ট "বার্তা" (বা পদ্ধতি) এর প্রতিক্রিয়া দেয় কিনা।

তাহলে রুবিতে স্ট্যাটিক টাইপিং নিয়ে বিরক্ত কেন, আপনি জিজ্ঞাসা করতে পারেন? যদিও এটি অবশ্যই কোন প্রতিষেধক নয় যা আপনার কোডকে জাদুকরী বাগ মুক্ত করে তুলবে, তবে এটি কিছু সুবিধা প্রদান করে:

  • শুদ্ধতা:স্ট্যাটিক টাইপিং নির্দিষ্ট ক্লাস প্রতিরোধে ভাল বাগগুলির, যেমন উপরে উল্লিখিত NoMethodError .
  • টুলিং:প্রায়শই, ডেভেলপমেন্টের সময় স্ট্যাটিক টাইপ তথ্য পাওয়া গেলে আরও ভাল টুলিং বিকল্পের দিকে নিয়ে যায় (যেমন IDE-তে রিফ্যাক্টরিং সমর্থন ইত্যাদি)
  • ডকুমেন্টেশন:অনেক স্ট্যাটিকালি টাইপ করা ল্যাঙ্গুয়েজে চমৎকার বিল্ট-ইন ডকুমেন্টেশন টুল রয়েছে। Haskell's Hoogle এটিকে একটি সার্চ ইঞ্জিন অফার করে দারুণ প্রভাব ফেলতে ব্যবহার করে যেখানে ফাংশনগুলি তাদের টাইপ স্বাক্ষর দ্বারা দেখা যেতে পারে৷
  • পারফরম্যান্স:কম্পাইলারের কাছে যত বেশি তথ্য উপলভ্য, তত বেশি পারফরম্যান্স অপ্টিমাইজেশন যা সম্ভাব্যভাবে প্রয়োগ করা যেতে পারে।

এই তালিকাটি সম্পূর্ণ নয়, এবং কেউ এই পয়েন্টগুলির বেশিরভাগের জন্য পাল্টা উদাহরণ খুঁজে পেতে পারে, তবে অবশ্যই তাদের কাছে সত্যের একটি মূল রয়েছে৷

ক্রমিক প্রকার পরীক্ষা করা হচ্ছে

সাম্প্রতিক বছরগুলিতে সাধারণত "ক্রমিক টাইপ চেকিং" নামে পরিচিত একটি পদ্ধতি বিভিন্ন গতিশীলভাবে টাইপ-চেক করা ভাষায় প্রবেশ করেছে:JS-এর জন্য TypeScript থেকে PHP-এর জন্য হ্যাক এবং পাইথনের জন্য mypy। এই পন্থাগুলির মধ্যে যা মিল রয়েছে তা হল যে তাদের সব-অথবা-কিছুই নয় এমন পদ্ধতির প্রয়োজন হয় না, বরং বিকাশকারীদেরকে ধীরে ধীরে ভেরিয়েবল এবং অভিব্যক্তিতে টাইপ তথ্য যোগ করার অনুমতি দেয় যেভাবে তারা উপযুক্ত মনে করে। এটি বিদ্যমান বৃহৎ কোডবেসগুলির জন্য বিশেষভাবে উপযোগী, যেখানে কেউ সিস্টেমের সবচেয়ে গুরুত্বপূর্ণ অংশগুলিকে স্থিরভাবে পরীক্ষা করতে পারে যখন বাকিগুলি টাইপ না করা এবং রানটাইমে চেক করা থাকে। রুবির জন্য সমস্ত প্রকার চেকিং সমাধান যা আমরা এই নিবন্ধের বাকি অংশে অন্বেষণ করব একই পদ্ধতি অনুসরণ করে৷

বিকল্পগুলি

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

শরবেট

স্ট্রাইপ দ্বারা তৈরি, শরবেট বর্তমানে রুবির জন্য সবচেয়ে আলোচিত টাইপ চেকিং সমাধান, অন্তত এই কারণে নয় যে শপিফাই, গিটল্যাব, কিকস্টার্টার এবং কয়েনবেসের মতো বড় কোম্পানিগুলি বন্ধ বিটা পর্বের সময় প্রাথমিকভাবে গ্রহণকারী ছিল। এটি মূলত গত বছরের রুবি কাইগির সময় ঘোষণা করা হয়েছিল এবং এই বছরের 20শে জুন এটির প্রথম সর্বজনীন রিলিজ দেখেছিল৷ Sorbet আধুনিক C++ এ লেখা হয়েছে এবং ম্যাটজের পছন্দ (উদ্ধৃতি:"আমি টাইপ টীকা ঘৃণা করি") সত্ত্বেও, টাইপ টীকাগুলির উপর ভিত্তি করে একটি পদ্ধতির জন্য বেছে নেওয়া হয়েছে। শরবত সম্পর্কে একটি বিশেষ আকর্ষণীয় বিষয় হল যে এটি স্ট্যাটিক এবং ডাইনামিক টাইপ চেকিংয়ের সমন্বয়ের জন্য বেছে নেয় যেহেতু রুবির অত্যন্ত গতিশীল প্রকৃতি এবং মেটাপ্রোগ্রামিং ক্ষমতা স্ট্যাটিক টাইপ সিস্টেমের জন্য চ্যালেঞ্জিং।

# typed: true
class Test
  extend T::Sig
 
  sig {params(x: Integer).returns(String)}
  def to_s(x)
    x.to_s
  end
end

টাইপ চেকিং সক্ষম করতে, আমাদের প্রথমে # typed: true যোগ করতে হবে ম্যাজিক কমেন্ট করুন এবং T::Sig দিয়ে আমাদের ক্লাস প্রসারিত করুন মডিউল প্রকৃত টাইপ টীকা sig দিয়ে নির্দিষ্ট করা হয়েছে পদ্ধতি:

sig {params(x: Integer).returns(String)}

যা নির্দিষ্ট করে যে এই পদ্ধতিটি x নামে একটি একক আর্গুমেন্ট নেয় যেটা Integer টাইপের এবং একটি String প্রদান করে . ভুল আর্গুমেন্ট টাইপ দিয়ে এই পদ্ধতিটিকে কল করার চেষ্টা করলে একটি ত্রুটি দেখা দেবে:

Test.new.to_s("42")
# Expected Integer but found String("42") for argument x

এই মৌলিক চেকগুলি ছাড়াও, শরবতের আরও কয়েকটি কৌশল রয়েছে তার হাতা উপরে। উদাহরণস্বরূপ, এটি আমাদের ভয়ঙ্কর NoMethodError থেকে বাঁচাতে পারে nil-এ :

users = T::Array[User].new
user = users.first
user.username
 
# Method username does not exist on NilClass component of T.nilable(User)

উপরের স্নিপেটটি User এর একটি খালি অ্যারেকে সংজ্ঞায়িত করে বস্তু এবং যখন আমরা প্রথম উপাদানটি অ্যাক্সেস করার চেষ্টা করি (যা nil ফেরত দেবে ) শরবত সঠিকভাবে আমাদের সতর্ক করে যে username নামে কোন পদ্ধতি নেই NilClass-এ উপলব্ধ . যাইহোক, যদি আমরা নিশ্চিত হই যে একটি নির্দিষ্ট মান কখনই nil হতে পারে না , আমরা T.must ব্যবহার করতে পারি শরবতকে এটি জানাতে:

users = T::Array[User].new
user = T.must(users.first)
user.username

যদিও উপরের কোডটি এখন চেক টাইপ করবে, এটি রানটাইম ব্যতিক্রম হতে পারে, তাই এই বৈশিষ্ট্যটি যত্ন সহকারে ব্যবহার করুন৷

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

উপরন্তু, শরবত "রুবি ইন্টারফেস" ফাইলগুলির সাথেও কাজ করতে পারে (rbi ) যা এটি একটি sorbet/ এ রাখে আপনার বর্তমান কাজের ডিরেক্টরিতে ফোল্ডার। এটি আমাদের একটি প্রকল্পের ব্যবহৃত সমস্ত রত্নগুলির জন্য ইন্টারফেস সংজ্ঞা তৈরি করতে দেয়, যা আমাদের আরও বেশি ধরনের ত্রুটি খুঁজে পেতে সাহায্য করতে পারে৷

শরবেতের আরও অনেক কিছু আছে যা আমরা একটি নিবন্ধে কভার করতে পারি (যেমন বিভিন্ন কঠোরতা মাত্রা বা মেটাপ্রোগ্রামিং প্লাগইন), কিন্তু এর ডকুমেন্টেশন ইতিমধ্যেই বেশ ভালো এবং পিআর-এর জন্য উন্মুক্ত।

খাড়া

শরবতের সবচেয়ে পরিচিত বিকল্প হল সুতারো মাতসুমোটোর স্টিপ। এটি টীকা ব্যবহার করে না এবং নিজে থেকে কোনো প্রকার অনুমান করে না। পরিবর্তে, এটি সম্পূর্ণরূপে .rbi-এর উপর নির্ভর করে sig-এ ফাইলগুলি ডিরেক্টরি।

চলুন নিচের সাধারণ রুবি ক্লাস থেকে শুরু করা যাক:

class User
  attr_reader :first_name, :last_name, :address
 
  def initialize(first_name, last_name, address)
    @first_name = first_name
    @last_name = last_name
    @address = address
  end
 
  def full_name
    "#{first_name} #{last_name}"
  end
end

আমরা এখন একটি প্রাথমিক user.rbi স্ক্যাফোল্ড করতে পারি নিম্নলিখিত কমান্ড সহ ফাইল:

$ steep scaffold user.rb > sig/user.rbi

এটি নিম্নলিখিত ফাইলে পরিণত হয় যা একটি সূচনা বিন্দু হিসাবে তৈরি করা হয়েছে (সকল প্রকার any হিসাবে নির্দিষ্ট করা হয়েছে তা দ্বারা চিত্রিত , যা কোন নিরাপত্তা প্রদান করে না):

class User
  @first_name: any
  @last_name: any
  @address: any
  def initialize: (any, any, any) -> any
  def full_name: () -> String
end

যাইহোক, যদি আমরা এই সময়ে চেক টাইপ করার চেষ্টা করি, আমরা কিছু ত্রুটির সম্মুখীন হব:

$ steep check
user.rb:11:7: NoMethodError: type=::User, method=first_name (first_name)
user.rb:11:21: NoMethodError: type=::User, method=last_name (last_name)

আমরা এইগুলি দেখার কারণ হল যে attr_reader এর মাধ্যমে কোন পদ্ধতিগুলিকে সংজ্ঞায়িত করা হয়েছে তা জানতে স্টিপের একটি বিশেষ মন্তব্যের প্রয়োজন s, তাই আসুন এটি যোগ করি:

# @dynamic first_name, last_name, address
attr_reader :first_name, :last_name, :address

উপরন্তু, আমাদের তৈরি করা .rbi পদ্ধতির সংজ্ঞা যোগ করতে হবে ফাইল আমরা এটিতে থাকাকালীন, আসুন any থেকে স্বাক্ষরগুলিও পরিবর্তন করি প্রকৃত প্রকারে:

class User
  @first_name: String
  @last_name: String
  @address: Address
  def initialize: (String, String, Address) -> any
  def first_name: () -> String
  def last_name: () -> String
  def address: () -> Address
  def full_name: () -> String
end

এখন, সবকিছু প্রত্যাশিতভাবে কাজ করে এবং steep check কোনো ত্রুটি ফেরত দেয় না।

আমরা এখন পর্যন্ত যা দেখেছি তার উপরে, স্টিপ জেনেরিককেও সমর্থন করে (যেমন Hash<Symbol, String> ) এবং ইউনিয়ন প্রকার, যা বিভিন্ন প্রকারের মধ্যে একটি হয়-বা পছন্দের প্রতিনিধিত্ব করে। উদাহরণস্বরূপ, একজন ব্যবহারকারীর top_post পদ্ধতিটি ব্যবহারকারীর দ্বারা লিখিত সর্বোচ্চ-র্যাঙ্কযুক্ত পোস্ট বা nil ফেরত দিতে পারে যদি তারা এখনও কিছু অবদান না করে থাকে। এটি ইউনিয়ন টাইপ (Post | nil) এর মাধ্যমে উপস্থাপন করা হয় , এবং সংশ্লিষ্ট স্বাক্ষর এইরকম দেখাবে:

def top_post: () -> (Post | nil)

যদিও স্টিপ-এর অবশ্যই শরবতের তুলনায় কম বৈশিষ্ট্য রয়েছে, এটি এখনও একটি সহায়ক টুল এবং ম্যাটজ রুবি 3-এ টাইপ চেক করার মত দেখতে যা কল্পনা করেছিলেন তার সাথে আরও বেশি সঙ্গতিপূর্ণ বলে মনে হচ্ছে।

রুবি টাইপ প্রোফাইলার

কুকপ্যাড থেকে Yusuke Endoh (রুবি ডেভেলপার সার্কেলে "mame" নামে বেশি পরিচিত) Ruby Type Profiler নামে একটি তথাকথিত লেভেল 1 টাইপ চেকারে কাজ করছে। এখানে উপস্থাপিত অন্যান্য সমাধানগুলির বিপরীতে, এটির স্বাক্ষর ফাইল বা টাইপ টীকাগুলির প্রয়োজন নেই বরং এটি পার্স করার সময় রুবি প্রোগ্রাম সম্পর্কে যতটা সম্ভব অনুমান করার চেষ্টা করে। যদিও এটি স্টিপ বা শরবতের তুলনায় অনেক কম সম্ভাব্য সমস্যা দেখা দেয়, তবে এটি বিকাশকারীর কাছে কোনো অতিরিক্ত খরচ ছাড়াই আসে।

সারাংশ

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


  1. আপনি কোন রুবি আইডিই ব্যবহার করবেন?

  2. রুবি কনস্ট্যান্টস সম্পর্কে আপনার যা জানা দরকার

  3. পিসি ধীর গতিতে চলছে? আপনি হার্ডওয়্যার প্রতিস্থাপন শুরু করার আগে দশটি জিনিস পরীক্ষা করতে হবে

  4. Windows 10 এ RAM টাইপ কিভাবে চেক করবেন