এটি খুব সম্ভবত আপনি UndefinedConversionError
এর মত একটি রুবি ব্যতিক্রম দেখেছেন অথবা IncompatibleCharacterEncodings
. আপনি ব্যতিক্রম মানে কি তা বুঝতে পেরেছেন এমন সম্ভাবনা কম। এই নিবন্ধটি সাহায্য করবে. আপনি শিখবেন কিভাবে অক্ষর এনকোডিং কাজ করে এবং কিভাবে রুবিতে প্রয়োগ করা হয়। শেষ পর্যন্ত, আপনি এই ত্রুটিগুলি আরও সহজে বুঝতে এবং ঠিক করতে সক্ষম হবেন।
তাই যাইহোক একটি "ক্যারেক্টার এনকোডিং" কি?
প্রতিটি প্রোগ্রামিং ভাষায়, আপনি স্ট্রিং দিয়ে কাজ করেন। কখনও কখনও আপনি তাদের ইনপুট হিসাবে প্রক্রিয়া, কখনও কখনও আপনি আউটপুট হিসাবে তাদের প্রদর্শন. কিন্তু আপনার কম্পিউটার "স্ট্রিংস" বোঝে না। এটি শুধুমাত্র বিট বোঝে:1s এবং 0s। স্ট্রিংগুলিকে বিটে রূপান্তর করার প্রক্রিয়াটিকে অক্ষর এনকোডিং বলা হয়।
কিন্তু অক্ষর এনকোডিং শুধুমাত্র কম্পিউটারের যুগের অন্তর্গত নয়। আমরা কম্পিউটারের আগে একটি সহজ প্রক্রিয়া থেকে শিখতে পারি:মোর্স কোড।
মোর্স কোড
মোর্স কোড এর সংজ্ঞায় খুবই সহজ। আপনার কাছে দুটি প্রতীক বা একটি সংকেত তৈরি করার উপায় রয়েছে (ছোট এবং দীর্ঘ)। এই দুটি চিহ্ন দিয়ে, আপনি একটি সাধারণ ইংরেজি বর্ণমালার প্রতিনিধিত্ব করেন। যেমনঃ
- A হল .- (একটি ছোট চিহ্ন এবং একটি দীর্ঘ চিহ্ন)
- ই হল। (একটি সংক্ষিপ্ত চিহ্ন)
- O হল --- (তিনটি লম্বা চিহ্ন)
এই সিস্টেমটি 1837 সালের দিকে উদ্ভাবিত হয়েছিল এবং এটি শুধুমাত্র দুটি চিহ্ন বা সংকেত সহ সমগ্র বর্ণমালাকে এনকোড করার অনুমতি দেয়৷
আপনি এখানে একজন অনুবাদকের সাথে অনলাইনে খেলতে পারেন।
ছবিতে আপনি একটি "এনকোডার" দেখতে পাচ্ছেন, যিনি বার্তাগুলিকে এনকোডিং এবং ডিকোড করার জন্য দায়ী৷ এটি শীঘ্রই কম্পিউটারের আগমনের সাথে পরিবর্তিত হবে৷
ম্যানুয়াল থেকে স্বয়ংক্রিয় এনকোডিং
একটি বার্তা এনকোড করার জন্য, আপনাকে একজন ব্যক্তিকে ম্যানুয়ালি অক্ষরগুলিকে মোর্স কোডের অ্যালগরিদম অনুসরণ করে চিহ্নগুলিতে অনুবাদ করতে হবে৷
মোর্স কোডের মতো, কম্পিউটারগুলি শুধুমাত্র দুটি "প্রতীক" ব্যবহার করে:1 এবং 0। আপনি কম্পিউটারে শুধুমাত্র এইগুলির একটি ক্রম সঞ্চয় করতে পারেন, এবং যখন সেগুলি পড়া হয়, তখন সেগুলিকে এমনভাবে ব্যাখ্যা করতে হবে যা ব্যবহারকারীর কাছে বোধগম্য হয়৷
উভয় ক্ষেত্রেই প্রক্রিয়াটি এভাবে কাজ করে:
Message -> Encoding -> Store/Send -> Decoding -> Message
মোর্স কোডে এসওএস এটি হবে:
SOS -> Encode('SOS') -> ...---... -> Decode('...---...') -> SOS
----------------------- --------------------------
Sender Receiver
কম্পিউটার এবং অন্যান্য প্রযুক্তির সাথে একটি বড় পরিবর্তন হল যে এনকোডিং এবং ডিকোডিং প্রক্রিয়াটি স্বয়ংক্রিয়ভাবে করা হয়েছিল তাই আমাদের আর তথ্য অনুবাদ করার জন্য লোকের প্রয়োজন নেই৷
যখন কম্পিউটার উদ্ভাবিত হয়েছিল, তখন অক্ষরগুলিকে স্বয়ংক্রিয়ভাবে 1s এবং 0s-এ রূপান্তরিত করার জন্য তৈরি করা প্রাথমিক মানগুলির মধ্যে একটি ছিল (যদিও প্রথম নয়) ছিল ASCII৷
ASCII হল আমেরিকান স্ট্যান্ডার্ড কোড ফর ইনফরমেশন ইন্টারচেঞ্জ। "আমেরিকান" অংশটি একটি গুরুত্বপূর্ণ ভূমিকা পালন করেছিল কিভাবে কম্পিউটার কিছু সময়ের জন্য তথ্য নিয়ে কাজ করে; কেন তা আমরা পরবর্তী বিভাগে দেখব।
ASCII (1963)
মোর্স কোড এবং খুব প্রাথমিক কম্পিউটারের মত টেলিগ্রাফিক কোডের জ্ঞানের উপর ভিত্তি করে, একটি কম্পিউটারে এনকোডিং এবং অক্ষর ডিকোড করার জন্য একটি মান 1963 সালের দিকে তৈরি করা হয়েছিল। এই সিস্টেমটি তুলনামূলকভাবে সহজ ছিল কারণ এটি প্রথমে শুধুমাত্র 127টি অক্ষর কভার করে, ইংরেজি বর্ণমালা এবং অতিরিক্ত চিহ্ন।
ASCII প্রতিটি অক্ষরকে একটি দশমিক সংখ্যার সাথে সংযুক্ত করে কাজ করেছে যা বাইনারি কোডে অনুবাদ করা যেতে পারে। আসুন একটি উদাহরণ দেখি:
ASCII তে "A" হল 65, তাই আমাদের 65 কে বাইনারি কোডে অনুবাদ করতে হবে।
যদি আপনি না জানেন যে এটি কীভাবে কাজ করে, এখানে একটি দ্রুত উপায় রয়েছে :আমরা 65 কে 2 দ্বারা ভাগ করা শুরু করি এবং 0 না পাওয়া পর্যন্ত চালিয়ে যাই। যদি ভাগ সঠিক না হয়, আমরা অবশিষ্ট হিসাবে 1 যোগ করি:
65 / 2 = 32 + 1
32 / 2 = 16 + 0
16 / 2 = 8 + 0
8 / 2 = 4 + 0
4 / 2 = 2 + 0
2 / 2 = 1 + 0
1 / 2 = 0 + 1
এখন, আমরা অবশিষ্টাংশগুলি গ্রহণ করি এবং তাদের বিপরীত ক্রমে রাখি:
1000001
তাই আমরা "A" কে মূল ASCII এনকোডিং সহ "1000001" হিসাবে সংরক্ষণ করব, যা এখন US-ASCII নামে পরিচিত৷ আজকাল, 8-বিট কম্পিউটারের সাথে সাধারণ, এটি 01000001 হবে (8 বিট =1 বাইট)।
আমরা প্রতিটি অক্ষরের জন্য একই প্রক্রিয়া অনুসরণ করি, তাই 7 বিট সহ, আমরা 2^7 অক্ষর =127 পর্যন্ত সংরক্ষণ করতে পারি।
এখানে সম্পূর্ণ টেবিল আছে:
(https://www.plcdev.com/ascii_chart থেকে)
ASCII এর সমস্যা
আমরা যদি ফ্রেঞ্চ ç বা জাপানি অক্ষর 大 এর মতো আরেকটি অক্ষর যোগ করতে চাই তাহলে কী হবে?
হ্যাঁ, আমাদের একটি সমস্যা হবে৷
৷ASCII-এর পরে, লোকেরা তাদের নিজস্ব এনকোডিং সিস্টেম তৈরি করে এই সমস্যাটি সমাধান করার চেষ্টা করেছিল। তারা আরও বিট ব্যবহার করেছিল, কিন্তু এটি অবশেষে অন্য সমস্যা সৃষ্টি করেছিল।
মূল সমস্যাটি ছিল যে একটি ফাইল পড়ার সময়, আপনি জানেন না যে আপনার একটি নির্দিষ্ট এনকোডিং সিস্টেম আছে কিনা। এটিকে একটি ভুল এনকোডিং দিয়ে ব্যাখ্যা করার প্রচেষ্টার ফলে "���" বা "Ã,ÂÂÂÂ" এর মতো বিদ্রুপের সৃষ্টি হয়।
সেই এনকোডিং সিস্টেমের বিবর্তন ছিল বড় এবং প্রশস্ত। ভাষার উপর নির্ভর করে, আপনার বিভিন্ন সিস্টেম ছিল। চীনাদের মতো আরও অক্ষর সহ ভাষাগুলিকে তাদের বর্ণমালা এনকোড করার জন্য আরও জটিল সিস্টেম তৈরি করতে হয়েছিল৷
বহু বছর এর সাথে লড়াই করার পর, একটি নতুন মান তৈরি করা হয়েছিল:ইউনিকোড। এই স্ট্যান্ডার্ডটি আধুনিক কম্পিউটারের তথ্য এনকোড এবং ডিকোড করার পদ্ধতিকে সংজ্ঞায়িত করে।
ইউনিকোড (1988)
ইউনিকোডের লক্ষ্য খুবই সহজ। এর অফিসিয়াল সাইট অনুসারে:"প্ল্যাটফর্ম, প্রোগ্রাম বা ভাষা যাই হোক না কেন, প্রতিটি চরিত্রের জন্য একটি অনন্য নম্বর প্রদান করতে।"
তাই একটি ভাষার প্রতিটি অক্ষরের জন্য একটি অনন্য কোড বরাদ্দ করা হয়েছে, এটি একটি কোড পয়েন্ট হিসাবেও পরিচিত। বর্তমানে 137,000 টিরও বেশি অক্ষর রয়েছে৷
ইউনিকোড স্ট্যান্ডার্ডের অংশ হিসাবে, আমাদের কাছে সেই মানগুলি বা কোড পয়েন্টগুলিকে এনকোড করার বিভিন্ন উপায় রয়েছে, তবে UTF-8 সবচেয়ে বিস্তৃত৷
একই লোকেরা যারা গো প্রোগ্রামিং ভাষা তৈরি করেছে, রব পাইক এবং কেন থম্পসন, তারাও UTF-8 তৈরি করেছে। এটি সফল হয়েছে কারণ এটি কীভাবে সেই সংখ্যাগুলিকে এনকোড করে তাতে দক্ষ এবং চতুর। দেখা যাক ঠিক কেন।
UTF-8:ইউনিকোড ট্রান্সফরমেশন ফরম্যাট (1993)
UTF-8 এখন ওয়েবসাইটগুলির জন্য ডি ফ্যাক্টো এনকোডিং (94% এর বেশি ওয়েবসাইটগুলি সেই এনকোডিং ব্যবহার করে)। এটি অনেক প্রোগ্রামিং ভাষা এবং ফাইলের জন্য ডিফল্ট এনকোডিং। তাহলে কেন এটি এত সফল ছিল এবং এটি কীভাবে কাজ করে?
UTF-8, অন্যান্য এনকোডিং সিস্টেমের মতো, কম্পিউটারে সংরক্ষণ করার জন্য ইউনিকোডে সংজ্ঞায়িত সংখ্যাগুলিকে বাইনারিতে রূপান্তরিত করে৷
UTF-8 এর দুটি অত্যন্ত গুরুত্বপূর্ণ দিক রয়েছে:- বিটগুলি সংরক্ষণ করার সময় এটি কার্যকরী, যেহেতু একটি অক্ষর 1 থেকে 4 বাইট নিতে পারে৷- ইউনিকোড এবং গতিশীল পরিমাণ বাইট ব্যবহার করে, এটি ASCII এনকোডিংয়ের সাথে সামঞ্জস্যপূর্ণ কারণ প্রথম 127 অক্ষর 1 বাইট নেয়। এর মানে আপনি UTF-8 হিসাবে একটি ASCII ফাইল খুলতে পারেন।
আসুন UTF-8 কীভাবে কাজ করে তা ভেঙে দেওয়া যাক।
1 বাইট সহ UTF-8
ইউনিকোড টেবিলের মানের উপর নির্ভর করে, UTF-8 বিভিন্ন সংখ্যক অক্ষর ব্যবহার করে।
প্রথম 127 এর সাথে, এটি নিম্নলিখিত টেমপ্লেট ব্যবহার করে:Rust1
0_______
সুতরাং 0 সর্বদা সেখানে থাকবে, তারপরে বাইনারি সংখ্যাটি ইউনিকোডে মানকে প্রতিনিধিত্ব করে (যা ASCIIও হবে)। যেমন:A =65 =1000001।
স্ট্রিং:
-এ আনপ্যাক পদ্ধতি ব্যবহার করে রুবির সাথে এটি পরীক্ষা করা যাক'A'.unpack('B*').first
# 01000001
B এর অর্থ হল আমরা প্রথমে সবচেয়ে উল্লেখযোগ্য বিট সহ বাইনারি বিন্যাস চাই। এই প্রেক্ষাপটে, এর মানে হল সর্বোচ্চ মানের বিট। তারকাচিহ্নটি রুবিকে আরও বিট না হওয়া পর্যন্ত চালিয়ে যেতে বলে। যদি আমরা পরিবর্তে একটি সংখ্যা ব্যবহার করি, তাহলে আমরা শুধুমাত্র সেই সংখ্যা পর্যন্ত বিটগুলি পেতে পারি:
'A'.unpack('B4').first
# 01000
2 বাইট সহ UTF-8
যদি আমাদের কাছে এমন একটি অক্ষর থাকে যার মান বা কোড পয়েন্ট ইউনিকোডে 127 এর বাইরে, 2047 পর্যন্ত, আমরা নিম্নলিখিত টেমপ্লেট সহ দুটি বাইট ব্যবহার করি:
110_____ 10______
তাই ইউনিকোডে মানের জন্য আমাদের কাছে 11টি খালি বিট রয়েছে। আসুন একটি উদাহরণ দেখি:
ইউনিকোডে À হল 192, তাই বাইনারিতে এটি 11000000, 8 বিট নেয়। এটি প্রথম টেমপ্লেটের সাথে খাপ খায় না, তাই আমরা দ্বিতীয়টি ব্যবহার করি:
110_____ 10______
আমরা ডান থেকে বামে শূন্যস্থান পূরণ করা শুরু করি:
110___11 10000000
সেখানে খালি বিট দিয়ে কি হবে? আমরা শুধু 0s রাখি, তাই চূড়ান্ত ফলাফল হল:11000011 10000000।
আমরা এখানে একটি প্যাটার্ন দেখতে শুরু করতে পারেন. যদি আমরা বাম থেকে ডানে পড়া শুরু করি, 8 বিটের প্রথম গ্রুপের শুরুতে দুটি 1s আছে। এটি বোঝায় যে অক্ষরটি 2 বাইট নিতে যাচ্ছে:
11000011 10000000
--
আবার, আমরা রুবি:
দিয়ে এটি পরীক্ষা করতে পারি'À'.unpack('B*').first
# 1100001110000000
এখানে একটি ছোট টিপ হল যে আমরা আউটপুটকে আরও ভালভাবে ফর্ম্যাট করতে পারি:
'À'.unpack('B8 B8').join(' ')
# 11000011 10000000
আমরা 'À'.unpack('B8 B8')
থেকে একটি অ্যারে পাই এবং তারপরে আমরা একটি স্ট্রিং পেতে একটি স্পেস সহ উপাদানগুলির সাথে যোগদান করি। আনপ্যাক প্যারামিটারের 8s রুবিকে 2টি গ্রুপে 8 বিট পেতে বলে।
3 বাইট সহ UTF-8
যদি একটি অক্ষরের জন্য ইউনিকোডের মান পূর্ববর্তী টেমপ্লেটে উপলব্ধ 11 বিটের সাথে মানানসই না হয়, তাহলে আমাদের একটি অতিরিক্ত বাইট প্রয়োজন:
1110____ 10______ 10______
আবার, টেমপ্লেটের শুরুতে তিনটি 1s আমাদের বলে যে আমরা একটি 3-বাইট অক্ষর পড়তে চলেছি৷
এই টেমপ্লেটে একই প্রক্রিয়া প্রয়োগ করা হবে; ইউনিকোড মানকে বাইনারিতে রূপান্তর করুন এবং ডান থেকে বামে স্লটগুলি পূরণ করা শুরু করুন। এর পরে যদি আমাদের কিছু খালি জায়গা থাকে তবে সেগুলি 0s দিয়ে পূরণ করুন।
4 বাইট সহ UTF-8
কিছু মান আমাদের আগের টেমপ্লেটে থাকা 11টি খালি বিটের থেকেও বেশি নেয়। আসুন ইমোজি 🙂 সহ একটি উদাহরণ দেখি, যা ইউনিকোডের জন্য "a" বা "大" এর মতো একটি অক্ষর হিসাবেও দেখা যেতে পারে।
ইউনিকোডে "🙂" এর মান বা কোড পয়েন্ট হল 128578৷ বাইনারিতে সেই সংখ্যাটি হল:11111011001000010, 17 বিট৷ এর মানে হল এটি 3-বাইট টেমপ্লেটে ফিট করে না যেহেতু আমাদের শুধুমাত্র 16টি খালি স্লট ছিল, তাই আমাদের একটি নতুন টেমপ্লেট ব্যবহার করতে হবে যা মেমরিতে 4 বাইট নেয়:
11110___ 10______ 10______ 10______
আমরা আবার শুরু করি বাইনারিতে সংখ্যা দিয়ে পূরণ করে:Rust1
11110___ 10_11111 10011001 10000010
এবং এখন, আমরা বাকিগুলি 0s দিয়ে পূরণ করুন:Rust1
1111000 10011111 10011001 10000010
দেখা যাক রুবিতে এটি কেমন দেখাচ্ছে৷
৷যেহেতু আমরা ইতিমধ্যেই জানি যে এটি 4 বাইট নেবে, তাই আমরা আউটপুটে আরও ভাল পঠনযোগ্যতার জন্য অপ্টিমাইজ করতে পারি:
'🙂'.unpack('B8 B8 B8 B8').join(' ')
# 11110000 10011111 10011001 10000010
কিন্তু যদি আমরা তা না করি, আমরা শুধু ব্যবহার করতে পারতাম:
'🙂'.unpack('B*')
আমরা একটি অ্যারেতে বাইটগুলি বের করার জন্য "বাইট" স্ট্রিং পদ্ধতিও ব্যবহার করতে পারি:
"🙂".bytes
# [240, 159, 153, 130]
এবং তারপর, আমরা উপাদানগুলিকে বাইনারিতে ম্যাপ করতে পারি:
"🙂".bytes.map {|e| e.to_s 2}
# ["11110000", "10011111", "10011001", "10000010"]
এবং যদি আমরা একটি স্ট্রিং চাই, আমরা join:
ব্যবহার করতে পারি"🙂".bytes.map {|e| e.to_s 2}.join(' ')
# 11110000 10011111 10011001 10000010
ইউটিএফ-৮-এ ইউনিকোডের জন্য প্রয়োজনের চেয়ে বেশি জায়গা রয়েছে
UTF-8 এর আরেকটি গুরুত্বপূর্ণ দিক হল যে এটিতে সমস্ত ইউনিকোড মান (বা কোড পয়েন্ট) অন্তর্ভুক্ত করা যেতে পারে -- এবং শুধুমাত্র আজকে বিদ্যমান নয় বরং ভবিষ্যতেও বিদ্যমান থাকবে।
কারণ UTF-8-এ, 4-বাইট টেমপ্লেট সহ, আমাদের পূরণ করার জন্য 21টি স্লট আছে। তার মানে আমরা 2^21 (=2,097,152) মান পর্যন্ত সঞ্চয় করতে পারি, প্রায় 1.1 মিলিয়ন ইউনিকোড মানের চেয়ে অনেক বেশি।
এর মানে আমরা এই আত্মবিশ্বাসের সাথে UTF-8 ব্যবহার করতে পারি যে নতুন অক্ষর বা ভাষা বরাদ্দ করার জন্য ভবিষ্যতে আমাদের অন্য এনকোডিং সিস্টেমে স্যুইচ করতে হবে না৷
রুবিতে বিভিন্ন এনকোডিংয়ের সাথে কাজ করা
রুবিতে, আমরা এই কাজটি করে একটি প্রদত্ত স্ট্রিং এর এনকোডিং এখনই দেখতে পারি:
'Hello'.encoding.name
# "UTF-8"
আমরা একটি ভিন্ন এনকোডিং সিস্টেমের সাথে একটি স্ট্রিং এনকোড করতে পারি। যেমনঃ
encoded_string = 'hello, how are you?'.encode("ISO-8859-1", "UTF-8")
encoded_string.encoding.name
# ISO-8859-1
রূপান্তরটি সামঞ্জস্যপূর্ণ না হলে, আমরা ডিফল্টরূপে একটি ত্রুটি পাই। ধরা যাক আমরা "হ্যালো 🙂" কে UTF-8 থেকে ASCII তে রূপান্তর করতে চাই৷ যেহেতু ইমোজি "🙂" ASCII-এর সাথে খাপ খায় না, তাই আমরা পারি না। রুবি সেই ক্ষেত্রে একটি ত্রুটি উত্থাপন করে:
"hello 🙂".encode("ASCII", "UTF-8")
# Encoding::UndefinedConversionError (U+1F642 from UTF-8 to US-ASCII)
কিন্তু রুবি আমাদের ব্যতিক্রম করার অনুমতি দেয় যেখানে, যদি একটি অক্ষর এনকোড করা না যায় তবে আমরা এটিকে "?" দিয়ে প্রতিস্থাপন করতে পারি।
"hello 🙂".encode("ASCII", "UTF-8", undef: :replace)
# hello ?
আমাদের কাছে নতুন এনকোডিংয়ে একটি বৈধ অক্ষর দিয়ে নির্দিষ্ট অক্ষর প্রতিস্থাপন করার বিকল্পও রয়েছে:
"hello 🙂".encode("ASCII", "UTF-8", fallback: {"🙂" => ":)"})
# hello :)
রুবিতে একটি স্ক্রিপ্টের একটি স্ক্রিপ্টের এনকোডিং পরিদর্শন করা হচ্ছে
আপনি যে স্ক্রিপ্ট ফাইলটিতে কাজ করছেন তার এনকোডিং দেখতে, ".rb" ফাইল, আপনি নিম্নলিখিতগুলি করতে পারেন:
__ENCODING__
# This will show "#<Encoding:UTF-8>" in my case.
রুবি 2.0 থেকে, রুবি স্ক্রিপ্টগুলির জন্য ডিফল্ট এনকোডিং হল UTF-8, কিন্তু আপনি প্রথম লাইনে একটি মন্তব্যের মাধ্যমে এটি পরিবর্তন করতে পারেন:
# encoding: ASCII
__ENCODING__
# #<Encoding:US-ASCII>
কিন্তু UTF-8 স্ট্যান্ডার্ডে লেগে থাকা ভালো যদি না আপনার কাছে এটি পরিবর্তন করার খুব ভালো কারণ থাকে।
রুবিতে এনকোডিং নিয়ে কাজ করার জন্য কিছু টিপস
আপনি Encoding.name_list
সহ রুবিতে সমর্থিত এনকোডিংগুলির সম্পূর্ণ তালিকা দেখতে পারেন . এটি একটি বড় অ্যারে ফিরিয়ে দেবে:
["ASCII-8BIT", "UTF-8", "US-ASCII", "UTF-16BE", "UTF-16LE", "UTF-32BE", "UTF-32LE", "UTF-16", "UTF-32", "UTF8-MAC"...
ইংরেজি ভাষার বাইরে অক্ষর নিয়ে কাজ করার সময় অন্য গুরুত্বপূর্ণ দিকটি হল রুবি 2.4 এর আগে, কিছু পদ্ধতি যেমন upcase
অথবা reverse
আশানুরূপ কাজ করেনি। উদাহরণস্বরূপ, রুবি 2.3-এ, আপকেস আপনি যেমন ভাবেন তেমন কাজ করে না:
# Ruby 2.3
'öıüëâñà'.upcase
# 'öıüëâñà'
সমাধানটি অ্যাক্টিভসাপোর্ট ব্যবহার করছিল, রেল থেকে বা অন্য কোনও বাহ্যিক রত্ন, কিন্তু রুবি 2.4 থেকে আমাদের কাছে সম্পূর্ণ ইউনিকোড কেস ম্যাপিং রয়েছে:
# From Ruby 2.4 and up
'öıüëâñà'.upcase
# 'ÖIÜËÂÑÀ'
ইমোজির সাথে কিছু মজা
ইউনিকোড এবং রুবিতে ইমোজি কীভাবে কাজ করে তা দেখা যাক:
'🖖'.chars
# ["🖖"]
এটি হল "মধ্যম এবং রিং ফিঙ্গারগুলির মধ্যে অংশ নিয়ে উত্থাপিত হাত", যা "ভলকান স্যালুট" ইমোজি নামেও পরিচিত৷ আমাদের যদি একই ইমোজি থাকে কিন্তু অন্য স্কিন টোনে যা ডিফল্ট না হয়, তাহলে আকর্ষণীয় কিছু ঘটে:
'🖖🏾'.chars
# ["🖖", "🏾"]
তাই শুধু একটি অক্ষর হওয়ার পরিবর্তে, আমাদের কাছে একটি একক ইমোজির জন্য দুটি রয়েছে৷
কি ঘটেছিল?
ঠিক আছে, ইউনিকোডে কিছু অক্ষরকে বিভিন্ন অক্ষরের সংমিশ্রণ হিসাবে সংজ্ঞায়িত করা হয়েছে। এই ক্ষেত্রে, কম্পিউটার যদি এই দুটি অক্ষর একসাথে দেখে, তবে এটি শুধুমাত্র একটি দেখায় এবং ত্বকের টোন প্রয়োগ করা হয়।
আরেকটি মজার উদাহরণ আছে যা আমরা পতাকা দিয়ে দেখতে পারি।
'🇦🇺'.chars
# ["🇦", "🇺"]
ইউনিকোডে, পতাকা ইমোজিগুলি অভ্যন্তরীণভাবে কিছু বিমূর্ত ইউনিকোড অক্ষর দ্বারা উপস্থাপিত হয় যাকে "আঞ্চলিক নির্দেশক চিহ্ন" বলা হয় যেমন 🇦 বা 🇿। এগুলি সাধারণত বাইরের পতাকা ব্যবহার করা হয় না, এবং কম্পিউটার যখন দুটি চিহ্ন একসাথে দেখে, তখন সেই সংমিশ্রণের জন্য একটি থাকলে পতাকাটি দেখায়৷
নিজের জন্য দেখতে, এটি অনুলিপি করার চেষ্টা করুন এবং যেকোনো পাঠ্য সম্পাদক বা ক্ষেত্রের কমাটি সরান:
🇦,🇺
উপসংহার
আমি আশা করি ইউনিকোড এবং UTF-8 কীভাবে কাজ করে এবং কীভাবে তারা রুবি এবং সম্ভাব্য ত্রুটিগুলির সাথে সম্পর্কিত এই পর্যালোচনাটি আপনার জন্য দরকারী ছিল৷
নেওয়ার জন্য সবচেয়ে গুরুত্বপূর্ণ পাঠটি হল মনে রাখা যে আপনি যখন কোনও ধরণের পাঠ্যের সাথে কাজ করছেন তখন আপনার কাছে একটি যুক্ত এনকোডিং সিস্টেম রয়েছে এবং এটি সংরক্ষণ বা পরিবর্তন করার সময় এটি উপস্থিত রাখা গুরুত্বপূর্ণ। যদি আপনি পারেন, UTF-8 এর মতো একটি আধুনিক এনকোডিং সিস্টেম ব্যবহার করুন যাতে ভবিষ্যতে আপনাকে এটি পরিবর্তন করতে হবে না৷
রুবি রিলিজ সম্পর্কে নোট
আমি এই নিবন্ধের সমস্ত উদাহরণের জন্য রুবি 2.6.5 ব্যবহার করেছি। আপনি একটি অনলাইন REPL-এ বা স্থানীয়ভাবে আপনার টার্মিনালে গিয়ে irb
চালাতে চেষ্টা করতে পারেন। আপনি যদি রুবি ইনস্টল করে থাকেন।
যেহেতু শেষ প্রকাশগুলিতে ইউনিকোড সমর্থন উন্নত করা হয়েছে, তাই আমি সর্বশেষটি ব্যবহার করতে বেছে নিয়েছি তাই এই নিবন্ধটি প্রাসঙ্গিক থাকবে। যাই হোক না কেন, রুবি 2.4 এবং তার উপরে, সমস্ত উদাহরণ এখানে দেখানো হিসাবে কাজ করা উচিত।