কম্পিউটার টিউটোরিয়াল

রুবি দিয়ে কমান্ড লাইন দক্ষতা: একটি প্র্যাক্টিক্যাল গাইড

কমান্ড লাইন আসলভাবে দক্ষ হওয়ার জন্য আপনাকে দশক ও না হলে শতকরা শত ছোট ইউটিলিটি প্রোগ্রামে দক্ষ হতে হবে। প্রতিটিই কিছুটা ভিন্নভাবে কাজ করে। এটি ভয়াবহ একঘার হতে পারে।

সৌভাগ্যtois, রুবি যেন একটি জেনারেল-পারপাস প্রোগ্রামিং ল্যাঙ্গুয়েজের মতো এই একক-উদ্দেশ্য টুলগুলোর অনেকটিকে রিপ্লেস করা সম্ভব। সেভাবে আপনি আপনার বিদ্যমান রুবি জ্ঞান ব্যবহার করে আপনার কমান্ড-লাইন-ফু লেভেল আপ করতে পারেন।

এই পোস্ট আপনাকে রুবি কমান্ড-লাইন স্বিস আর্মি নাইফ হিসেবে ব্যবহার করার ফান্ডামেন্টেলস শিখাবে। আমি আপনাকে চমৎকার এক-লাইনার দিয়ে বমবার্ড করব না। বরং আমরা দেখব কীভাবে জিনিসগুলো আসলে কাজ করে, যাতে আপনি আপনার সমস্যা সমাধানে এই টেকনিকগুলো প্রয়োগ করতে পারেন।

কমান্ড লাইন থেকে রুবি ব্যবহার

আপনি নিশ্চিত জানেন যে রুবি প্রোগ্রাম কমান্ড লাইন থেকে এভাবে চালানো যায়:

$ ruby myprogram.rb

কিন্তু কি আপনি জানেন যে আপনি রুবি এক্সিকিউট করার জন্য কোড পাইপ করাতে পারেন?

$ echo "puts 2+2" | ruby
4

আরও উপকারী হচ্ছে কমান্ড-লাইন আর্গুমেন্ট হিসেবে কোড পাস করা। এটিই আজ আমাদের মূল ফোকাস।

$ ruby -e 'puts 2+2'
4

হে নতুনরা

উপরের উদাহরণগুলো কি বিভ্রান্তিকর লাগছে? এর কারণ হতে পারে আপনি পাইপ এবং রিডাইরেকশনের সাথে পরিচিত নন। এর জন্য একটি ভালো ইন্ট্রো পড়ুন। আমরা নিচে অনেক পাইপ ব্যবহার করব।

ইনপুট সহ কাজ

বেশির ভাগ কমান্ড-লাইন টুল কিছু ডেটা ইনপুট নেয়, প্রসেস করে, এবং আউটপুট দেয়।

ইনপুট নেওয়ার আমাদের দুটি ভালো অপশন আছে: কমান্ড-লাইন আর্গুমেন্ট এবং STDIN। দুটোই দেখি।

কমান্ড-লাইন আর্গুমেন্ট

আপনি আপনার স্ক্রিপ্টে যেকোনো সংখ্যক কমান্ড-লাইন আর্গুমেন্ট পাস করতে পারেন। বাকি সবার পরে সেগুলো দিয়ে দিন:

$ ruby -e '<your code here>' arg1 arg2 arg3 etc

এই আর্গুমেন্টগুলো ARGV অ্যারে সংরক্ষিত থাকে। নিচের উদাহরণে আমি পুরো অ্যারে ডাম্প করছি যাতে আপনি দেখতে পান কী আছে।

$ ruby -e 'puts ARGV.inspect' apples bananas pears oranges
["apples", "bananas", "pears", "oranges"]

দ্রষ্টব্য, এটি ঠিক রুবির সাধারণ আচরণ। কমান্ড লাইন ব্যবহার করলেই কোনো ম্যাজিক হয় না। ARGV সম্পর্কে আরও জানতে এই পোস্ট দেখুন।

বোকা উদাহরণ

একটু কল্পনা করুন যে আমি অতিশয় আত্মমুগ্ধ। আমার জন্য সবচেয়ে গুরুত্বপূর্ণ বিষয় হচ্ছে ওয়েবে আমার নাম কতবার উল্লেখ হয়েছে। আমরা যা টেকনিক শিখলাম সেটি ব্যবহার করে আমি সহজে একটি এক-লাইনার লিখতে পারি যেকোনো ওয়েবপেজের জন্য এটি ক্যালকুলেট করতে।

$ ruby -e "require 'open-uri'; puts open(ARGV.first).read.scan(/starr/i).count" <url here>

STDIN

কমান্ড-লাইন আর্গুমেন্ট চমৎকার, কিন্তু সেগুলো শুধু ছোট মানগুলোর জন্য ভালো। আপনি সেগুলো ব্যবহার করবেন না—মান लीজিয়ে—মবি ডিকের সম্পূর্ণ পাঠ্য ইনপুট করার জন্য। সেক্ষেত্রে আমরা STDIN ব্যবহার করব।

আপনি যদি STDIN-র সাথে পরিচিত না হন, ভয় পাওয়ার কিছু নেই। আমাদের উদ্দেশ্যে এটি অন্য যেকোনো রিড-ওপেন ফাইলের মতো আচরণ করে।

নিচে আমি কী করছি। উদাহরণে আমরা কিছু টেক্সট রুবিতে পাইপ করছি। আমাদের রুবি স্ক্রিপ্ট STDIN থেকে পড়ে স্ক্রিনে প্রিন্ট করছে।

echo "bananas!" | ruby -e "puts STDIN.read"
bananas!

আমরা cat ব্যবহার করে বড় পরিমাণ ডেটা সহজে ইনপুট করতে পারি। নিচের উদাহরণে first মেথড ব্যবহার করা হয়েছে যেকোনো ফাইলের জন্য উপলব্ধ, টেক্সটের প্রথম কয়েক লাইন পাওয়ার জন্য:

cat moby.txt | ruby -e "puts STDIN.first(3)"
Call me Ishmael. Some years ago--never mind how long precisely--having little or no money in my purse, and nothing particular to interest me on shore, I thought I would sail about a little and see the watery part of

বোকা উদাহরণ

এখন আমরা STDIN কনজিউম করতে জানি, তাই উপরের বোকা উদাহরণটি রিরাইট করি। রুবি দিয়ে ওয়েবপেজ ফেচ করার বদলে, আমরা curl ব্যবহার করব এবং রুবি শুধু প্যাটার্ন ম্যাচের জন্য ব্যবহার করব।

curl <MY URL> | ruby -e "puts STDIN.read.scan(/starr/i).size"

সিনট্যাক্টিক শুগার সহ STDIN!

STDIN নিয়ে কাজ করার সময় প্রতিটি লাইনループ করা খুব সাধারণ। কল্পনা করুন আমি একটি ডিরেক্টরির প্রতিটি ফাইলের এক্সটেনশন পেতে চাই। এখানে নরমাল STDIN লুপ ব্যবহার করে কীভাবে করব:

ls | ruby -e 'STDIN.each_line { |l| puts l.split(".").last }'
rb
rb
csv

যেহেতু STDIN লুপ খুব কমন, রুবি একটি শর্টহ্যান্ড দিয়েছে। আপনি যদি স্ক্রিপ্টটি -n ফ্ল্যাগ দিয়ে চালান, রুবি অটোমেটিক্যালি STDIN-এর প্রতিটি লাইন লুপ করবে। বর্তমান লাইন গ্লোভাল ভেরিয়েবল $_-তে থাকে।

তাই উপরের উদাহরণটি এভাবে রিরাইট করা যায়:

ls | ruby -n -e 'puts $_.split(".").last'

আপনার ইচ্ছা শর্টহ্যান্ড ব্যবহার করবেন কিনা। নিশ্চিতভাবে এটি কম কোড লিখতে হয়, কিন্তু এর মানে আপনাকে আরও আربیট্রারি ফ্যাক্ট মনে রাখতে হয় যেমন -n এবং $_।

আউটপুট সহ কাজ

এমন পরিস্থিতিতে আপনি সাধারণত আউটপুট STDOUT-এ লিখতে চান। এটি সর্বাধিক ফ্লেক্সিবিলিটি দেয় কারণ এটি আউটপুট অন্য প্রোগ্রামে পাইপ করতে বা ডিস্কে রিডাইরেক্ট করতে দেয়।

ভালো খবর হলো আপনি उन्हीं প্রিন্ট কমান্ড ব্যবহার করতে পারেন যেগুলো আপনি ভালোভাবে জানেন। একটা বিষয় খেয়াল রাখতে হবে puts একটি নিউলাইন যোগ করে, যা আপনি চাইতে পারেন বা চাইতে না পারেন।

puts "hello world" # "hello world\n" STDOUT-এ পাঠায়
print "hello world" # নিউলাইন যোগ করে না

সবকিছু একসাথে

Honeybadger ইউএস-র ওয়াশিংটন স্টেট-এ বেসড। এর মানে আমাদের প্রিভিলেজ আছে ওয়াশিংটনে বাস করা প্রতিটি পেয়িং কাস্টমারের জন্য সেলস ট্যাক্স দিতে।

আমি এটি খুব সহজ করে ফেললাম, কিন্তু বেসিক্যালি আমাদের কাছে একটি CSV ফাইল আছে বছরের প্রতিটি ট্রানজেকশনের জন্য। এটা কিছু এইরকম দেখায়:

1/1/2015,100.00,WA
1/1/2015,50.00,NY

তাই ওয়াশিংটনের সব ট্রানজেকশনের দ্রুত সমষ্টি পেতে আমি একটি এক-লাইনার ব্যবহার করতে পারি:

$ cat cc.csv | ruby -e 'puts STDIN.inject(0) { |sum, x| date, amount, state = x.split(","); state.strip == "WA" ? sum + amount.to_f : sum }'

খেয়াল রাখুন এটি CSV ফাইল পার্স করার খুব খারাপ পদ্ধতি। আমি এই কোড কখনো প্রোডাকশনে পাঠাব না। কিন্তু ছোট ছোট প্রোগ্রাম লিখে এককালীন সমস্যা সমাধান করার आनন্দের একটা হচ্ছে আপনি সব এজ কেস ইগনোর করতে পারেন। এখানে আমি সেটিই করছি।

  1. রুবি কোড উন্নত করুন: ক্লিনার OOP ডিজাইনের জন্য Cohesion & Coupling আয়ত্ত করুন

  2. গুগল TCMalloc দিয়ে রুবির মেমরি অ্যালোকেশন প্রোফাইলিং

  3. রুবি পার্সিং মास্টার: স্ক্র্যাচ থেকে নিজস্ব পার্সার বানান

  4. আইডি ওয়াচডগের সাথে পরিচয় রক্ষা করুন: ১৩ বছরের বিশ্বস্ত সুরক্ষা