RBS হল রুবির জন্য একটি নতুন ধরনের সিনট্যাক্স বিন্যাস ভাষার নাম। RBS আপনাকে .rbs নামে একটি নতুন এক্সটেনশন সহ ফাইলগুলিতে আপনার রুবি কোডে টাইপ টীকা যোগ করতে দেয় . তারা দেখতে এইরকম:
class MyClass
def my_method : (my_param: String) -> String
end
RBS এর সাথে টাইপ টীকা প্রদান করে আপনি সুবিধা পাবেন যেমন:
- আপনার কোডবেসের গঠন সংজ্ঞায়িত করার একটি পরিষ্কার এবং সংক্ষিপ্ত উপায়।
- সরাসরি ক্লাস পরিবর্তন করার পরিবর্তে ফাইলের মাধ্যমে আপনার লিগ্যাসি কোডে প্রকার যোগ করার একটি নিরাপদ উপায়।
- স্ট্যাটিক এবং ডাইনামিক টাইপ চেকারগুলির সাথে সর্বজনীনভাবে একীভূত হওয়ার সম্ভাবনা।
- পদ্ধতি ওভারলোডিং, হাঁস টাইপিং, গতিশীল ইন্টারফেস এবং আরও অনেক কিছু মোকাবেলা করার জন্য নতুন বৈশিষ্ট্য।
কিন্তু অপেক্ষা করো! শরবত এবং খাড়ার মতো স্ট্যাটিক টাইপ চেকার নেই?
হ্যাঁ, এবং তারা মহান! যাইহোক, চার বছর আলোচনার পর এবং সম্প্রদায়-নির্মিত টাইপ চেকারদের একটি মুষ্টিমেয়, রুবি কমিটর টিম ভেবেছিল যে টাইপ চেকার সরঞ্জাম তৈরির জন্য কিছু মান নির্ধারণ করার সময় এসেছে৷
আরবিএস আনুষ্ঠানিকভাবে একটি ভাষা, এবং এটি রুবি 3 এর সাথে জীবন্ত হয়ে উঠছে।
এছাড়াও, রুবির গতিশীলভাবে টাইপ করা প্রকৃতির কারণে, পাশাপাশি হাঁসের টাইপিং এবং পদ্ধতি ওভারলোডিংয়ের মতো সাধারণ প্যাটার্নের কারণে, সম্ভাব্য সর্বোত্তম পদ্ধতি নিশ্চিত করতে কিছু সতর্কতা অবলম্বন করা হচ্ছে, যা আমরা শীঘ্রই আরও বিশদে দেখতে পাব।
রুবি 3 ইনস্টল
৷এখানে দেখানো উদাহরণগুলি অনুসরণ করতে, আমাদের রুবি 3 ইনস্টল করতে হবে।
আপনি অফিসিয়াল নির্দেশাবলী অনুসরণ করে বা রুবি-বিল্ডের মাধ্যমে এটি করতে পারেন যদি আপনাকে অনেক রুবি সংস্করণ পরিচালনা করতে হয়।
বিকল্পভাবে, আপনি rbs
ও ইনস্টল করতে পারেন আপনার বর্তমান প্রকল্পে সরাসরি মণি:
gem install rbs
স্ট্যাটিক বনাম গতিশীল টাইপিং
আরও এগিয়ে যাওয়ার আগে, আসুন এই ধারণাটি পরিষ্কার করা যাক। কিভাবে গতিশীলভাবে টাইপ করা ভাষাগুলি স্ট্যাটিক ভাষার সাথে তুলনা করে?
রুবি এবং জাভাস্ক্রিপ্টের মতো গতিশীলভাবে টাইপ করা ভাষাগুলিতে, দোভাষীর জন্য কোনও পূর্বনির্ধারিত ডেটা টাইপ নেই যাতে রানটাইম চলাকালীন কোনও নিষিদ্ধ অপারেশন ঘটলে কীভাবে এগিয়ে যেতে হবে তা বোঝার জন্য৷
এটি স্ট্যাটিক টাইপিং থেকে যা আশা করা হয় তার বিপরীত। স্ট্যাটিকভাবে টাইপ করা ভাষা, যেমন জাভা এবং সি, কম্পাইলের সময় প্রকারগুলি যাচাই করে।
একটি রেফারেন্স হিসাবে নিম্নলিখিত জাভা কোড স্নিপেট নিন:
int number = 0;
number = "Hi, number!";
স্ট্যাটিক টাইপিংয়ে এটি সম্ভব নয়, যেহেতু দ্বিতীয় লাইনটি একটি ত্রুটি নিক্ষেপ করবে:
error: incompatible types: String cannot be converted to int
এখন, রুবিতে একই উদাহরণ নিন:
number = 0;
number = "Hi, number!";
puts number // Successfully prints "Hi, number!"
রুবিতে, একটি ভেরিয়েবলের ধরন ফ্লাইতে পরিবর্তিত হয়, যার অর্থ হল দোভাষী জানেন কিভাবে গতিশীলভাবে একটি থেকে অন্যটিতে অদলবদল করতে হয়৷
এই ধারণাটি সাধারণত দৃঢ়ভাবে টাইপ করা এর সাথে বিভ্রান্ত হয় বনাম দুর্বলভাবে টাইপ করা ভাষা।
রুবি শুধুমাত্র একটি গতিশীলভাবে টাইপ করা ভাষা নয়, যার মানে এটি একটি ভেরিয়েবলকে রানটাইমের সময় তার ধরন পরিবর্তন করতে দেয়। তবে এটি আপনাকে পাগল ধরনের মিক্সিং অপারেশন করার অনুমতি দেয় না।
পরবর্তী উদাহরণটি নিন (রুবিতে) আগেরটি থেকে অভিযোজিত:
number = 2;
sum = "2" + 2;
puts sum
এবার আমরা দুটি সংখ্যার যোগফল চেষ্টা করছি যা বিভিন্ন প্রকারের (একটি Integer
এবং একটি String
) রুবি নিম্নলিখিত ত্রুটি নিক্ষেপ করবে:
main.rb:2:in `+': no implicit conversion of Integer into String (TypeError)
from main.rb:2:in `<main>'
অন্য কথায়, রুবির বক্তব্য যে (সম্ভবত) বিভিন্ন ধরণের জটিল গণনা সম্পাদনের কাজটি আপনার।
জাভাস্ক্রিপ্ট, অন্যদিকে, যা দুর্বলভাবে এবং গতিশীলভাবে টাইপ করা, ভিন্ন ফলাফলের সাথে একই কোডের অনুমতি দেয়:
> number = 2
sum = "2" + 2
console.log(sum)
> 22 // it concatenates both values
আরবিএস শরবত থেকে কীভাবে আলাদা?
প্রথমত, প্রত্যেকটি কোড টীকা করার পদ্ধতি গ্রহণ করে। যখন শরবেট আপনার কোড জুড়ে স্পষ্টভাবে টীকা যোগ করে কাজ করে, RBS-এর জন্য কেবল .rbs দিয়ে একটি নতুন ফাইল তৈরি করা প্রয়োজন। এক্সটেনশন।
এর প্রাথমিক সুবিধা হল যখন আমরা উত্তরাধিকার কোডবেসগুলির স্থানান্তর সম্পর্কে চিন্তা করি। যেহেতু আপনার আসল ফাইলগুলি প্রভাবিত হবে না, তাই আপনার প্রকল্পগুলিতে RBS ফাইলগুলি গ্রহণ করা অনেক বেশি নিরাপদ৷
এর নির্মাতাদের মতে, RBS এর মূল লক্ষ্য হল গঠনটি বর্ণনা করা আপনার রুবি প্রোগ্রামের. এটি শুধুমাত্র ক্লাস/পদ্ধতি স্বাক্ষর সংজ্ঞায়িত করার উপর ফোকাস করে।
আরবিএস নিজেই চেক টাইপ করতে পারে না। এর লক্ষ্য টাইপ চেকার (যেমন শরবত এবং খাড়া) তাদের কাজ করার জন্য কাঠামোকে ভিত্তি হিসাবে সংজ্ঞায়িত করার মধ্যে সীমাবদ্ধ।
আসুন একটি সাধারণ রুবি উত্তরাধিকারের উদাহরণ দেখি:
class Badger
def initialize(brand)
@brand = brand
end
def brand?
@brand
end
end
class Honey < Badger
def initialize(brand: "Honeybadger", sweet: true)
super(brand)
@sweet = sweet
end
def sweet?
@sweet
end
end
দারুণ! কয়েকটি বৈশিষ্ট্য এবং অনুমানকৃত প্রকার সহ মাত্র দুটি ক্লাস।
নীচে, আমরা একটি সম্ভাব্য RBS উপস্থাপনা দেখতে পাচ্ছি:
class Brand
attr_reader brand : String
def initialize : (brand: String) -> void
end
class Honey < Brand
@sweet : bool
def initialize : (brand: String, ?sweet: bool) -> void
def sweet? : () -> bool
end
বেশ অনুরূপ, তাই না? এখানে প্রধান পার্থক্য হল প্রকার। initialize
Honey
এর পদ্ধতি ক্লাস, উদাহরণস্বরূপ, একটি String
পায় এবং একটি boolean
প্যারামিটার এবং কিছুই ফেরত দেয় না।
ইতিমধ্যে, শরবত টিম RBI (টাইপ ডেফিনেশনের জন্য শরবতের ডিফল্ট এক্সটেনশন) এবং RBS-এর মধ্যে আন্তঃকার্যযোগ্যতার অনুমতি দেওয়ার জন্য সরঞ্জাম তৈরির জন্য নিবিড়ভাবে কাজ করছে।
আরবিএসের টাইপ ডেফিনিশন ফাইলগুলি কীভাবে ব্যবহার করা যায় তা বোঝার জন্য শরবত এবং যে কোনও প্রকার পরীক্ষকের ভিত্তি তৈরি করাই লক্ষ্য।
স্ক্যাফোল্ডিং টুল
আপনি যদি ভাষা দিয়ে শুরু করেন এবং ইতিমধ্যে কিছু প্রকল্প চলছে, তাহলে আশেপাশের জিনিসগুলি কোথায় এবং কীভাবে টাইপ করা শুরু করবেন তা অনুমান করা কঠিন হতে পারে৷
এটি মাথায় রেখে, রুবি টিম আমাদের rbs
নামে একটি অত্যন্ত সহায়ক CLI টুল সরবরাহ করেছে বিদ্যমান ক্লাসের জন্য ভারা ধরনের।
উপলব্ধ কমান্ড তালিকাভুক্ত করতে, শুধু rbs help
টাইপ করুন কনসোলে এবং ফলাফল পরীক্ষা করুন:
CLI টুলে উপলব্ধ কমান্ড।
সম্ভবত তালিকার সবচেয়ে গুরুত্বপূর্ণ কমান্ড হল prototype
যেহেতু এটি "আনুমানিক" RBS কোড তৈরি করার জন্য একটি প্যারাম হিসাবে প্রদত্ত সোর্স কোড ফাইলের AST বিশ্লেষণ করে।
আনুমানিক কারণ এটি 100% কার্যকর নয়। যেহেতু আপনার লিগ্যাসি কোড প্রাথমিকভাবে টাইপ করা হয়নি, তাই এর বেশিরভাগ স্ক্যাফোল্ড করা বিষয়বস্তু একইভাবে আসবে। RBS কিছু ধরন অনুমান করতে পারে না যদি কোনো সুস্পষ্ট অ্যাসাইনমেন্ট না থাকে, উদাহরণস্বরূপ।
রেফারেন্স হিসাবে আরেকটি উদাহরণ নেওয়া যাক, এবার একটি ক্যাসকেডেড উত্তরাধিকারে তিনটি ভিন্ন শ্রেণী জড়িত:
class Animal
def initialize(weight)
@weight = weight
end
def breathe
puts "Inhale/Exhale"
end
end
class Mammal < Animal
def initialize(weight, is_terrestrial)
super(weight)
@is_terrestrial = is_terrestrial
end
def nurse
puts "I'm breastfeeding"
end
end
class Cat < Mammal
def initialize(weight, n_of_lives, is_terrestrial: true)
super(weight, is_terrestrial)
@n_of_lives = n_of_lives
end
def speak
puts "Meow"
end
end
বৈশিষ্ট্য এবং পদ্ধতি সহ শুধু সহজ ক্লাস। মনে রাখবেন যে তাদের মধ্যে একটি ডিফল্ট বুলিয়ান মান প্রদান করা হয়েছে, যা RBS নিজে থেকে অনুমান করার সময় কী সক্ষম তা প্রদর্শন করা গুরুত্বপূর্ণ।
এখন, এই ধরনের স্ক্যাফোল্ড করার জন্য, আসুন নিম্নলিখিত কমান্ডটি চালাই:
rbs prototype rb animal.rb mammal.rb cat.rb
আপনি যত খুশি রুবি ফাইল পাস করতে পারেন। নিম্নলিখিত এই মৃত্যুদন্ডের ফলাফল:
class Animal
def initialize: (untyped weight) -> untyped
def breathe: () -> untyped
end
class Mammal < Animal
def initialize: (untyped weight, untyped is_terrestrial) -> untyped
def nurse: () -> untyped
end
class Cat < Mammal
def initialize: (untyped weight, untyped n_of_lives, ?is_terrestrial: bool is_terrestrial) -> untyped
def speak: () -> untyped
end
আমরা যেমন ভবিষ্যদ্বাণী করেছি, ক্লাস তৈরি করার সময় আমরা যে ধরনের লক্ষ্য রেখেছিলাম তা RBS বুঝতে পারে না৷
আপনার বেশিরভাগ কাজ হবে ম্যানুয়ালি untyped
পরিবর্তন করা আসলদের রেফারেন্স। এটি সম্পন্ন করার আরও ভাল উপায় খুঁজে বের করার লক্ষ্যে কিছু আলোচনা এখনই সম্প্রদায়ে ঘটছে৷
মেটাপ্রোগ্রামিং
যখন মেটাপ্রোগ্রামিং আসে, তখন rbs
টুলটি তার গতিশীল প্রকৃতির কারণে খুব বেশি সাহায্য করবে না।
একটি উদাহরণ হিসাবে নিম্নলিখিত ক্লাস নিন:
class Meta
define_method :greeting, -> { puts 'Hi there!' }
end
Meta.new.greeting
নিম্নলিখিত এই ধরনের ভারা ফলাফল হবে:
class Meta
end
হাঁস টাইপিং
রুবি বস্তুর স্বভাব (তাদের প্রকার) নিয়ে খুব বেশি চিন্তা করে না তবে তারা কী করতে সক্ষম (তারা কী করে) সে বিষয়ে যত্ন নেয়।
হাঁস টাইপিং হল একটি বিখ্যাত প্রোগ্রামিং শৈলী যা নীতিবাক্য অনুসারে কাজ করে:
"যদি কোনো বস্তু হাঁসের মতো আচরণ করে (কথা বলা, হাঁটা, উড়ে যাওয়া, ইত্যাদি), তাহলে এটি একটি হাঁস"
অন্য কথায়, রুবি সর্বদা এটিকে হাঁসের মতো আচরণ করবে যদিও এর আসল সংজ্ঞা এবং প্রকারগুলি হাঁসের প্রতিনিধিত্ব করার কথা ছিল না।
যাইহোক, হাঁস টাইপিং কোড বাস্তবায়নের বিশদ বিবরণ লুকিয়ে রাখতে পারে যা সহজেই কঠিন এবং খুঁজে পাওয়া/পড়া কঠিন হতে পারে।
RBS ইন্টারফেস প্রকারের ধারণা চালু করেছে , যা পদ্ধতির একটি সেট যা কোন কংক্রিট ক্লাস বা মডিউলের উপর নির্ভর করে না।
আগের প্রাণীর উত্তরাধিকারের উদাহরণ নেওয়া যাক এবং ধরুন যে আমরা স্থলজ প্রাণীদের জন্য একটি নতুন শ্রেণিবদ্ধ স্তর যুক্ত করছি যেখান থেকে আমাদের Cat
এর উত্তরাধিকার হবে:
class Terrestrial < Animal
def initialize(weight)
super(weight)
end
def run
puts "Running..."
end
end
নন-টেরেস্ট্রিয়াল চিলড্রেন অবজেক্টকে চলা থেকে এড়াতে, আমরা একটি ইন্টারফেস তৈরি করতে পারি যা এই ধরনের ক্রিয়াকলাপের জন্য নির্দিষ্ট ধরনের পরীক্ষা করে:
interface _CanRun
# Requires `<<` operator which accepts `Terrestrial` object.
def <<: (Terrestrial) -> void
end
নির্দিষ্ট রান পদ্ধতিতে RBS কোড ম্যাপ করার সময়, এটি স্বাক্ষর হবে:
def run: (_CanRun) -> void
যখনই কেউ পদ্ধতিতে টেরেস্ট্রিয়াল অবজেক্ট ছাড়া অন্য কিছু পাস করার চেষ্টা করে, টাইপ চেকার ত্রুটিটি লগ করার বিষয়টি নিশ্চিত করবে৷
ইউনিয়নের প্রকারগুলি
৷রুবিবাদীদের মধ্যে বিভিন্ন ধরনের মান ধারণ করে এমন অভিব্যক্তি থাকাও সাধারণ।
def fly: () -> (Mammal | Bird | Insect)
RBS শুধুমাত্র পাইপ এর মাধ্যমে যোগদানের মাধ্যমে ইউনিয়নের ধরনগুলিকে মিটমাট করে অপারেটর।
পদ্ধতি ওভারলোডিং
আরেকটি সাধারণ অভ্যাস (আসলে অনেক প্রোগ্রামিং ভাষার মধ্যে) পদ্ধতি ওভারলোডিংয়ের অনুমতি দেওয়া, যেখানে একটি ক্লাসে একই নামের একাধিক পদ্ধতি থাকতে পারে কিন্তু স্বাক্ষরটি ভিন্ন (যেমন প্যারামের প্রকার বা সংখ্যা, তাদের ক্রম, ইত্যাদি। )।
আসুন একটি উদাহরণ নেওয়া যাক যেখানে একটি প্রাণী তার নিকটতম বিবর্তনীয় কাজিনদের ফিরিয়ে দিতে পারে:
def evolutionary_cousins: () -> Enumerator[Animal, void] | { (Animal) -> void } -> void
এইভাবে, আরবিএস আমাদের সুস্পষ্টভাবে নির্ধারণ করতে দেয় যে প্রদত্ত প্রাণীর একটি একক বিবর্তনীয় কাজিন বা তাদের একটি গুচ্ছ থাকবে কিনা।
TypeProf
সমান্তরালভাবে, রুবি টিম টাইপপ্রোফ নামে একটি নতুন প্রকল্পও শুরু করেছে, একটি পরীক্ষামূলক টাইপ-লেভেল রুবি ইন্টারপ্রেটার যার লক্ষ্য RBS বিষয়বস্তু বিশ্লেষণ এবং (প্রচেষ্টা) তৈরি করা।
এটি বিমূর্ত ব্যাখ্যার মাধ্যমে কাজ করে এবং এখনও আরও ভাল পরিমার্জনের দিকে প্রথম পদক্ষেপ নিচ্ছে, তাই উৎপাদনের উদ্দেশ্যে এটি ব্যবহার করার সময় সতর্ক থাকুন৷
এটি ইনস্টল করতে, কেবল আপনার প্রকল্পে রত্নটি যোগ করুন:
gem install typeprof
সচেতন থাকুন যে এটির জন্য 2.7 এর চেয়ে বেশি একটি রুবি সংস্করণ প্রয়োজন৷
Animal
এর নিম্নলিখিত সংস্করণটি নিন ক্লাস:
class Animal
def initialize(weight)
@weight = weight
end
def die(age)
if age > 50
true
elsif age <= 50
false
elsif age < 0
nil
end
end
end
Animal.new(100).die(65)
age
পদ্ধতির ভিতরে কি চলছে তার উপর ভিত্তি করে এবং একই পদ্ধতিতে আরও কল করলে, TypeProf বুদ্ধিমানের সাথে কোডে ম্যানিপুলেট করা প্রকারগুলি অনুমান করতে পারে৷
আপনি যখন typeprof animal.rb
চালান কমান্ড, এটি আউটপুট হওয়া উচিত:
## Classes
class Animal
@weight: Integer
def initialize: (Integer weight) -> Integer
def die: (Integer age) -> bool?
end
এটি একটি শক্তিশালী টুল যা ইতিমধ্যেই প্রচুর কোড চালু আছে এমন প্রকল্পগুলির জন্য অনেক কিছু অফার করে৷
VS কোড ইন্টিগ্রেশন
বর্তমানে, ফরম্যাটিং, স্ট্রাকচার চেকিং ইত্যাদির জন্য RBS-এর সাথে ডিল করার জন্য অনেকগুলি উপলব্ধ VS কোড প্লাগইন নেই। বিশেষ করে কারণ এটি এখনও তুলনামূলকভাবে নতুন।
যাইহোক, যদি আপনি "RBS" এর জন্য দোকানে অনুসন্ধান করেন তবে আপনি রুবি-স্বাক্ষর নামে একটি প্লাগইন খুঁজে পেতে পারেন যা সিনট্যাক্স হাইলাইট করতে সাহায্য করবে, যেমনটি নীচে দেখানো হয়েছে:
VS কোডে RBS সিনট্যাক্স হাইলাইট করা।
উপসংহার
RBS একেবারেই তাজা এবং ইতিমধ্যেই নিরাপদ রুবি কোডবেসগুলির দিকে একটি গুরুত্বপূর্ণ পদক্ষেপের প্রতিনিধিত্ব করে৷
৷সাধারণত, সময়ের সাথে সাথে নতুন টুলস এবং ওপেন-সোর্স প্রজেক্টগুলি এর ব্যাক আপ নিতে উঠবে, যেমন রুবি অন রেল অ্যাপ্লিকেশনের জন্য RBS ফাইল তৈরি করার জন্য RBS Rails।
ভবিষ্যত রুবি সম্প্রদায়ের জন্য নিরাপদ এবং আরও বাগ-মুক্ত অ্যাপ্লিকেশন সহ আশ্চর্যজনক জিনিস ধারণ করে৷ এটা দেখার জন্য অপেক্ষা করতে পারছি না!