ক্রিসমাসে নতুন রুবি ভার্সন প্রকাশ করা একটি রীতিমতো প্রথা হয়ে উঠেছে।
এই পোস্টে আমি রুবি ২.৪-এর কিছু সবচেয়ে আকর্ষণীয় পরিবর্তন কভার করব যাতে আপনি খবরগুলোতে আপ-টু-ডেট থাকতে পারেন 🙂
ফ্লোট#রাউন্ড কিওয়ার্ডসহ
যদি আপনার অ্যাপে ফ্লোট ব্যবহার করেন তবে আমি আশা করি আপনি রাউন্ডিং-এর জন্য floor বা ceil ব্যবহার করছেন, কারণ Float#round মেথডের ডিফল্ট আচরণ রুবি ২.৪-এ পরিবর্তিত হচ্ছে।
উদাহরণ:
# Ruby 2.3 (2.5).round # 3 # Ruby 2.4 (2.5).round # 2
ডিফল্ট আচরণ এখন হলো "রাউন্ড-টু-নিয়रेস্ট-ইভেন"।
আপডেট:
Float#round-এর ডিফল্ট আচরণRuby 2.4-এর চূড়ান্ত সংস্করণে আবার "রাউন্ডিং আপ"-এ ফিরে আসেছে। এই সিদ্ধান্ত ম্যাটজ এই পোস্ট 본래 প্রকাশিত হওয়ার পর নিয়েছিলেন।
তদুপরি, Float#round এখন একটি আর্গুমেন্ট নেয় যেটি দিয়ে আপনি আপনার পছন্দের রাউন্ডিং টাইপ নির্ধারণ করতে পারেন।
বিকল্পগুলো হলো:
- :even
- :up
- :down
উদাহরণ:
(4.5).round(half: :up) # 5
এছাড়া Float#floor, Float#ceil ও Float#truncate এখন একটি অপশনাল আর্গুমেন্ট নেয় যা দিয়ে আপনি প্রিসিশন সেট করতে পারেন।
IO মেথডের জন্য চম্প ফ্ল্যাগ
যদি আপনি কখনো gets বা each_line মেথড ব্যবহার করে থাকেন তবে আমি নিশ্চিত আপনি যেসব বিরক্তিকর নিউলাইন ক্যারেক্টারসহ কাজ করতে বাধ্য হয়েছিলেন সেটি মনে করছেন।
যেসবটা এমন দেখায়: \n।
বিগিনাররা সবসময় এই সমস্যায় পড়ে, কিন্তু এই নতুন ফিচারটি সাহায্য করতে পারে!
এখানে একটি উদাহরণ:
input = gets.chomp # "abc\n"
এখন রুবি ২.৪-এ আপনি chomp কিওয়ার্ড আর্গুমেন্ট সেট করতে পারবেন এবং gets নিউলাইন ক্যারেক্টারটি আপনার জন্য সরিয়ে দেবে।
উদাহরণ:
input = gets(chomp: true) # "abc"
এটি যেকোনো মান التي false বা nil নয় (রুবিতে এ 둘ই একমাত্র "ফ্যালসি" মান) সেটি কাজ করবে।
সুতরাং এটিও কাজ করবে (যদিও সুপারিশ করা হয় না কারণ এটি বিভ্রান্তি সৃষ্টি করতে পারে):
input = gets(chomp: 1234) # "abc"
এটি খুব বড় ব্যাপার নয়, কিন্তু এটি আপনাকে একটি মেথড কল বাঁচাতে পারে 🙂
পাথনেম#এম্পটি?
রুবি ২.৪-এ Dir#empty? ও File#empty? ইমপ্লিমেন্ট করা হয়েছে, এই মেথডগুলো দিয়ে আপনি চেক করতে পারেন একটি ডিরেক্টরি বা ফাইল খালি কিনা (এটা খুব স্পষ্ট ছিল, ঠিক ন?)।
কিন্তু Pathname#empty? ও সম্প্রতি যোগ করা হয়েছে।
যদি আপনি Pathname-এর সাথে পরিচিত না হন, তবে এটি একটি ক্লাস যা Dir ক্লাস ও File ক্লাস উভয়ের ফাংশনালিটি একসাথে মিলিয়ে দিয়েছে।
তদুপরি, এটি আরও "OO" (অবজেক্ট-ওরিয়েন্টেড) অর্থাৎ এটি স্ট্রিং না দিয়ে Pathname অবজেক্ট রিটার্ন করে।
উদাহরণ:
Pathname.empty?("ফাইল বা ডিরেক্টরি নাম")
কমিট: https://github.com/ruby/ruby/commit/9373c5efb993dd8cae0526118805449b19af2c22
সেট কমপেयर_বাই_আইডেন্টিটি
সেট হলো একটি ডেটা স্ট্রাকচার যা স্ট্যান্ডার্ড লাইব্রেরির অংশ হিসেবে উপলব্ধ। এটি আপনাকে ইউনিক আইটেমের একটি সংগ্রহ রাখতে সাহায্য করে।
ডিফল্টভাবে অবজেক্টগুলো তাদের ভ্যালুর 베이সিসে (বা আরও সঠিক বলে তাদের হ্যাশ ভ্যালুর 베이সিসে) কমপেয়ার করা হয়।
কিন্তু রুবি ২.৪-এ অবজেক্ট আইডি 베이স করে ইউনিক অবজেক্টের একটি সেট তৈরি করা সম্ভব।
উদাহরণ:
require 'set' # নরমাল সেট set = Set.new set << 123 << 123 << "abc" << "abc" # [123, "abc"] # আইডেন্টিটি সেট set = Set.new().compare_by_identity set << 123 << 123 << "abc" << "abc" # [123, "abc", "abc"]
যদি কেউ এই ফিচারের কোনো মজার ব্যবহার জানেন তবে কমেন্ট করে জানাবেন 🙂
কমিট: https://github.com/ruby/ruby/commit/76977611dd68e384fdce8c546efda5e1931e67a6
রিফাইনমেন্টস উইথ কার্নেল#সেন্ড, বেসিকঅবজেক্ট#সেন্ড, সিম্বল#টু_প্রক
এখানে আমি রিফাইনমেন্টস বিস্তারিত কভার করব না, কিন্তু বেসিক আইডিয়াটা হলো String এর মতো একটি ক্লাসে মেথড যোগ করা, একই সাথে এই পরিবর্তনটি "লোকালাইজড" রাখা একটি ফাইল বা ক্লাসে।
রুবি ২.৪ থেকে, রিফাইনমেন্টস দিয়ে ডিফাইন করা মেথডগুলো Kernel#send ও Symbol#to_proc এর মতো মেথড কল করার সময় উপলব্ধ থাকবে।
উদাহরণ:
module TenTimes
refine String do
def ten_times
puts self * 10
end
end
end
class Thing
using TenTimes
"abc".send(:ten_times)
end
আপনি যদি এটি ২.৩ বা তার নিচের ভার্সনে ট্রাই করেন তবে 'অনডিফাইনড মেথড' এরর পাবেন।
কমিট: https://github.com/ruby/ruby/commit/35a29390197750abf97ef16fa0740e377764daef
হ্যাশ#ট্রান্সফর্ম_ভ্যালুস
রেইলস থেকে এক্সট্র্যাক্ট করা আরেকটি মেথড যা সরাসরি রুবি-এ আসছে। আমি কথা বলছি Hash#transform_values এর কথা, যা Array#map-এর মতো কাজ করে।
উদাহরণ:
h = {a: 1, b: 2, c: 3}
h.transform_values { |v| v * 10 }
# {a: 10, b: 20, c: 30}
যদি আপনাকে ইন-প্লেস মিউটেশন দরকার হয় তবে Hash#transform_values! ও আছে।
কার্নেল#ক্লোন এখন অপশনাল কিওয়ার্ড আর্গুমেন্ট নেয়
আপনি যেন জানেন, একটি রুবি অবজেক্টের কপি তৈরি করা সম্ভব। এটি উপযোগী কারণ অধিকাংশ রুবি অবজেক্ট মিউটেবল এবং আপনি মূল অবজেক্টে পরিবর্তন এড়াতে চাইতে পারেন।
অবজেক্ট কপি করার জন্য আমাদের দুটি মেথড আছে:
- clone
- dup
clone ও dup-এর মধ্যে কিছু ছোট পার্থক্য আছে, কিন্তু এই পোস্টের জন্য শুধু বলি clone মূল অবজেক্টের "ফ্রোজেন" স্ট্যাটাস রাখে যখন dup রাখে না।
২.৪-এ নতুন হলো "ফ্রিজ" ফ্ল্যাগসহ clone কল করার ক্ষমতা।
উদাহরণ:
foo = "test".freeze boo = foo.clone(freeze: false) boo.frozen? # false
আমি নিশ্চিত নই এটি কতটুকু উপযোগী, কিন্তু কে অতিরিক্ত অপশন চায় না 🙂
কমিট: https://github.com/ruby/ruby/commit/320ae01c5fb091eab0926c186f304a9caeda1ace
থ্রেড#রিপোর্ট_অন_এক্সসেপশন
২.৪-এ আসা আরেকটি ফিচার হলো Thread.report_on_exception। এটি প্রপোজ করা হয়েছিল কারণ থ্রেড এক্সসেপশন ডিফল্টভাবে সাইলেন্ট, এবং এটি আপনার কোডের সমস্যাগুলো লুকিয়ে রাখতে পারে।
ডিফল্ট মান false, কিন্তু আপনার অ্যাপ যদি থ্রেড ব্যবহার করে তবে রুবি ২.৪-এ আপগ্রেড করার সময় এটি ইনেবল করার চেষ্টা করুন।
উদাহরণ:
Thread.report_on_exception = true t1 = Thread.new do puts "নতুন থ্রেডে" raise "থ্রেড থেকে এক্সসেপশন" end sleep(1) puts "মেইন থ্রেডে"
এটি এক্সসেপশন দেখাবে, কিন্তু আপনার প্রোগ্রাম ক্র্যাশ করবে না। বিকল্পটি হলো Thread.abort_on_exception, যা সবসময় থেকেই উপলব্ধ।
লক্ষ্য করুন যে এটার একটি ইনস্ট্যান্স ভার্সন ও আছে, সুতরাং আপনি সব থ্রেডের পরিবর্তে প্রতি-থ্রেড বেসিসেও এই অপশন সেট করতে পারেন।
বাইন্ডিং#আইআরবি
আপনি কি binding.pry ডিবাগিং-এর জন্য ব্যবহার করার পক্ষधर? যাক, এখন আমাদের কাছে binding.irb ও আছে যা একইভাবে কাজ করে।
কিন্তু যেহেতু এটি আইআরবি, আপনি প্রাই-এর মতো সিনট্যাক্স হাইলাইটিং পাবেন না।
যদি কোনো কারণে প্রাই অ্যাক্সেস না থাকে তবে কিছু না থাকার চেয়ে ভালো 🙂
কমিট: https://github.com/ruby/ruby/commit/493e48897421d176a8faf0f0820323d79ecdf94a
উপসংহার
রুবির এই নতুন ভার্সন অনেক আকর্ষণীয় ফিচার নিয়ে এসেছে, সুতরাং উপলব্ধ হলে অবশ্যই চেক আউট করুন।
এই পোস্ট শেয়ার করুন যাতে আরও অনেক মানুষ রুবি ২.৪-এর এই নতুন ফিচারগুলো সম্পর্কে জানতে পারে!