عبارات با قاعده در روبی

عبارات با قاعده یا Regular Expression ها چیزهایی هستند که همیشه میتوانند در راحت انجام شدن بسیاری از کارها به ما کمک کنند. برای مثال، فرض کنیم یک اسکریپتی داریم که میخواهد تعداد ایمیل های موجود در لیست کاربران را به ما بگوید. یا این که ببینیم چند درصد از کاربران، از جیمیل، یاهو یا هاتمیل استفاده میکنند. این یکی از استفاده های Regex هاست. به طور کلی، وقتی بدانیم رشته هایی با قواعد خاصی کنار هم چیده می‌شوند، میتوانیم با استفاده از Regex به سادگی الگویی پیاده کنیم که برای ما چک کند آیا ورودی از آن نوع هست یا نه.

الگوی کلی عبارات با قاعده در روبی، به شکل زیر است :

/[0-9a-zA-Z]/ #برای مجموعه ای از کرکترها
/hay/ #برای چک کردن یک قسمت خاص در یک رشته و تطبیق کلی
/\(\)/ #برای چک کردن نمادها

برای چک کردن برابری مقادیر یک رشته با الگوی خاص در روبی از === (سه علامت مساوی) استفاده میکنیم. بعنوان مثال، برنامه زیر به ما میگوید که مقدار وارد شده یک ایمیل است یا خیر :

/[0-9a-zA-Z]\@[0-9a-zA-Z]\.[a-z] === "a@gmail.com"

که این قطعه کد، مقدار true را برمیگرداند. چرا که الگوی کلی یک آدرس ایمیل را داده ایم . برای بهینه تر شدن، میتوانیم یک قطعه کد بنویسیم که چک کند کاربر از چه سرویس دهنده ای استفاده میکند.

if /[0-9a-zA-Z]\@gmail\.com/ === user.email
 puts "User #{user.username} uses Gmail"
end
if /[0-9a-zA-Z]\@yahoo\.com/ === user.email
 puts "User #{user.username} uses Yahoo!"
end

همچنین با استفاده از متد match میتوان چک کرد که آیا بخشی از عبارت ورودی، برابر الگوی وارد شده هست یا نه. برای مثال برنامه بالا را میتوانیم به این شکل بازنویسی کنیم :

if /\@gmail\.com/.match(user.email)
 puts "User #{user.username} uses Gmail"
end
if /\@yahoo\.com/.match(user.email)
 puts "User #{user.username} uses Yahoo!"
end

همچنین، میتوانیم با استفاده از براکت، از تکرار شدن الگوها جلوگیری کنیم. مثلا فرض کنیم قصد داریم ببینیم ورودی ای که کاربر به برنامه داده، یک دستور Lisp است یا خیر، پس به این شکل عمل خواهیم کرد :

/\([\+\-\*\/][0-9][0-9]\)/ === command

و با استفاده از این اساس، میتوان مبادرت به نوشتن Parser های مختلف نمود.

تا اینجا، تا حدودی با ساختار و کاربرد عبارات با قاعده در زبان روبی آشنا شدیم، در مباحث آینده به صورت عملی تر به موضوع خواهیم پرداخت.

 

برنامه نویسی پیشرفته در روبی – بخش سوم

در آموزش پیشین ، در مورد تبدیل نوع کلاس ها و همچنین ارث بری به قدر کافی صحبت شد. در این آموزش، قصد داریم تا در مورد «سر بارگذاری عملگرها» یا Operator Overloading بحث کنیم. وقتی یک کلاس جدید ایجاد میکنیم، به طور مستقیم نمی توانیم روی متغیرهای instance از عملگرها استفاده کنیم. به همین خاطر، مجبوریم که خودمان دوباره اپراتور ها را بازنویسی کنیم.

برای درک بهتر موضوع، وقتی یک عدد مانند ۱ را داخل یک متغیر قرار میدهید، یک شی از کلاس Fixnum ایجاد شده و این شی قابلیت این را دارد که با شی دیگری از کلاس Fixnum جمع بسته شود، از آن کم شود و … . بنابراین، نیاز به این داریم که تعریف کنیم عملگری مانند + وجود دارد که با استفاده از آن، میتوان عدد دیگری اضافه نمود. بیایید یک کلاس به نام TestNumber ایجاد کنیم و عملگر + را برایش تعریف کنیم.

class TestNumber
 def initialize(x)
  @x = x
 end
 def +(y)
  @x + y
 end
end

اگر دو شی از این کلاس ایجاد کنید و بخواهید روی آنها عملیات انجام دهید، حتما به مشکل میخورید. چرا که ما تعریف کردیم که متغیر x با y جمع شود و نه yی که در یک کلاس دیگر تعریف شده است.

برای این که x ما با yی که در یک کلاس دیگر تعریف شده است جمع بسته شود نیاز داریم تا متغیرهای instance آن کلاس را هم فراخوانی کنیم. پس کد ما به این شکل تغییر خواهد کرد :

class TestNumber
 attr_accessor :x
 def initialize(x)
  @x = x
 end
 def +(other)
  y = other.x
  TestNumber.new(@x + y)
 end
end

با استفاده از attr_accessor میتوانیم به متغیرهای instance دیگر کلاس ها دسترسی مستقیم داشته باشیم و مانند یک متد آنها را فراخوانی کنیم.

در این آموزش، مبحث Operator Overloading را پوشش دادیم. در آموزش های بعدی، به سایر مفاهیم و تکنیک های برنامه نویسی شی گرا در روبی خواهیم پرداخت.

برنامه نویسی پیشرفته در روبی – بخش دوم

در آموزش پیشین، در مورد ساخت کلاس و افزودن متد، بحث کردیم. در این آموزش، میخواهیم کمی آموزش را تعمیم دهیم، و درباره ارث بری صحبت کنیم. در آموزش قبلی، یک کلاس کاربر به این شکل تهیه کردیم :

class User
 def initialize(username, password)
  @username = username
  @password = password
 end
 def print_info
  puts "username: #{@username}"
  puts "password: #{@password.length * "*"}"
 end
end

بیایید یک برنامه بزرگ را در نظر بگیریم، مثلا قرار است از کاربرها، عده ای را به عنوان ادمین انتخاب کنیم، و عده ای را به عنوان ویرایشگر. باید چه کنیم؟ اولین راهی که به ذهن برنامه نویس تازه کار میرسد، نوشتن کلاس ادمین و ویرایشگر از صفر است. اما بیاید از ویژگی «ارث بری» یا Inheritance در روبی بهره ببریم.

نوشتن کلاس ویرایشگر و ادمین

همه زبان های شی گرا از ارث بری پشتیبانی میکنند. بیایید برسیم به این که در روبی، چگونه میتوان یک کلاس فرزند نوشت. کلاس والد ما، در این آموزش کلاس User است. کاربر عمومی، با گرفتن مجوزهایی تبدیل به ویرایشگر یا ادمین می شوند. به شکل زیر، کلاس خالی ادیتور را ایجاد میکنیم.

class Editor < User
end

باید مجوز های خاصی را به کلاس ویرایشگر اضافه کنیم. مثلا بگوییم میتواند ویرایش کند یا نه؟ میتواند کاربری را اضافه و حذف کند و … ! بیاییم با متد permissions مجوز ها را مشخص کنیم :

class Editor < User
 def permissions
  puts "Can Edit, Add and Remove Articles"
 end
end

و به همین ترتیب، کلاس ادمین را هم میسازیم :

class Admin < User
 def permissions
  puts "Can Edit, Add, Remove all Articles and Users"
 end
end

بدین شکل، کاربر ادمین هم ساختیم. حال سوال پیش می آید چگونه میتوان کلاس ها را به یکدیگر تبدیل نمود؟ مثلا کاربر عادی را به ادمین، ادیتور و ادمین را به یکدیگر و … ؟ در ادامه با ما باشید.

تبدیل نوع کلاس ها

ما اکنون سه کلاس Admin و Editor و User را داریم. برای این که این کلاس ها را به یکدیگر تبدیل کنیم باید چه کنیم؟ دقت کنید که نحوه تبدیل به این شکل است که کاربر، به ویرایشگر و ادمین؛ ادمین به کاربر و ویرایشگر ؛ و ویرایشگر به کاربر و ادمین تبدیل می شود. در واقع تبدیل نوع کلاس باید به این شکل باشد که کلاس جدیدی از نوع مورد نظر ما ایجاد شده، و اطلاعات آن منتقل شود. نمونه کد زیر، تبدیل کننده کاربر به ویرایشگر و ادمین است :

class User
 def initialize(username, password)
  @username = username
  @password = password
 end
 def print_info
  puts "username: #{@username}"
  puts "password: #{@password.length * "*"}"
 end
 def to_editor
  Editor.new(@username, @password)
 end
 def to_admin
  Admin.new(@username, @password)
 end
end

و به همین ترتیب، می توانید این متدها را برای دو نوع کاربر دیگر هم بنویسید ( که به علت طولانی شدن مطلب، از نوشتن آنها صرف نظر کردیم).

تا اینجا، با دو تا از مهم ترین تکنیک های شی گرایی در روبی آشنا شدیم. در آینده، سایر روش ها و تکنیک های برنامه نویسی شی گرا در روبی را نیز فراخواهیم گرفت.

برنامه نویسی پیشرفته در روبی – بخش اول

در کتاب آموزش روبی، در فصل آخر، خرده توضیحاتی را درباره شی گرایی در روبی آورده‌ایم، اما آن توضیحات برای کسی که بخواهد کد شی‌گرای واقعی بنویسد، کافی نیست. بنابراین، تصمیم بر آن شد تا در سلسله مقالاتی در این وبگاه، شی گرایی و برنامه نویسی پیشرفته در روبی را بررسی کنیم. در فصل آخر کتاب، به قدر کافی به مفاهیم تئوری شی گرایی (چهار مفهوم انتزاع، وراثت، چند ریختی و کپسوله سازی) پرداخته ایم، بنابراین از این مقاله، به صورت عملی مفاهیم مختلف را در روبی بررسی میکنیم.

ساختار کلی کلاس ها در روبی

کلاس ها در روبی به این شکل ساخته می شوند :

class Name
end

توجه داشته باشید که نام کلاس ها، حتما باید مانند ثوابت با حرف بزرگ انگلیسی شروع شود. مثلا اگر کلاس شما، کلاس Animal است، نمی توانید آن را به شکل animal نام گذاری کنید. در فاصله بین نام کلاس تا end ، متدهای یک کلاس را قرار میدهیم. مهم ترین متد هر کلاس، متد initialize است، که کلاس را مقداردهی اولیه میکند. برای مثال کلاس User را با دو مقدار اولیه username و password در نظر بگیرید :

class User
 def initialize(username, password)
  @username = username
  @password = password
 end
end

متغیرهایی که با @ شروع می شوند، متغیر های instance هستند، بدون دادن مقدار کافی به این متغیرها، کلاس(های) شما، ایجاد نمی شوند. به این شکل، یک شی از کلاس User ایجاد می کنیم :

user = User.new("username", 123456)

با استفاده از متد new ، مقدار دهی اولیه را انجام میدهیم. اما هنوز متدی در نظر نگرفته ایم که با استفاده از آن، بتوانیم یوزرنیم کاربر را دریافت کنیم، و پسورد کاربر را به شکل **** نشان دهیم، برای این کار، متد print_info را در کلاس User تعریف میکنیم.

class User
 def initialize(username, password)
  @username = username
  @password = password
 end
 def print_info
  puts "username: #{@username}"
  puts "password: #{@password.length * "*"}
 end
end

اکنون، متد مورد نظر ما قابلیت اجرایی شدن را داراست. پس با استفاده از print_info نتیجه مطلوب را دریافت خواهیم کرد.

توجه داشته باشید که این مقاله، آموزش ابتدایی و پایه‌ای برنامه سازی پیشرفته در روبی بود، در مقالات آینده، از امکانات بیشتری استفاده خواهیم نمود.

کار با کلاس File در روبی

در این مطلب، قصد ما اینست که کمی با کلاس File در روبی کار کرده و آشنا شویم، این کلاس برای ایجاد، خواندن و نوشتن، و تغییر در مجوز های فایل ها استفاده میگردد. ابتدا، مروری بر کلیدی ترین ویژگی های این کلاس میکنیم و سپس، با استفاده از آن، یک ویرایشگر متنی بسیار ساده مینویسیم.

ایجاد و حذف فایل ها

برای ایجاد یک فایل، کافیست به این شکل عمل کنیم :

File.new("Hello")

با استفاده از این متد، فایلی به نام Hello ایجاد میشود.

برای حذف یک فایل نیز، این چنین عمل میکنیم :

File.delete("Hello")

می توان گفت زمانی که قصد دارید برنامه‌تان خروجی را درون یک فایل (مثلا متنی) قرار دهد، مهم ترین متدهایی هستند که باید از آنها به درستی استفاده کنید. اکنون از این متدها گذشته و میرسیم به متد هایی که برای خواندن و نوشتن استفاده میکنیم.

خواندن و نوشتن

علاوه بر ایجاد و حذف فایل، خواندن و نوشتن نیز مقوله مهمی در کار با فایلهاست. برای خواندن و نوشتن، از دو متد open و close استفاده میشود. متد open همانگونه که از نامش پیداست، فایل مورد نظر را باز کرده و متد close آن را می بندد. گرچه open امکان ایجاد یک فایل جدید را نیز داراست. برای مثال برای چاپ خط به خط یک تکست و سپس بستن فایل در مفسر روبی، کد زیر بسیار کاراست :

f = File.open('text', 'r')
 
for line in f
 puts line
end
 
f.close

در خط اول، فایل را باز کرده و توسط پرچم r ، به مفسر، مجوز خواندن میدهیم. سپس توسط یک حلقه for ، خط به خط برنامه را روی صفحه ترمینال نمایش میدهیم و در آخر توسط متد close فایل مذکور را میبندیم. اکنون یک فایل متنی ایجاد کرده و درونش چند خطی مینویسیم.

f = File.open('text', 'w+')
 
f.write("Hello, World")
f.write("The End")
 
f.close

در اینجا، در خط اول با پرچم +w به مفسر مجوز نوشتن نیز میدهیم. اکنون نوبت آن است که با این ویژگی ها، یک ویرایشگر متنی درست کنیم :) برای نوشتن یک ویرایشگر متن ساده، تنها به چند چیز نیاز داریم، یک کلاس File ، یک حلقه تکرار و خواندن ورودی از طریق کی‌برد :

print 'Enter file name: '
name = gets.chomp
 
f = File.open(name, 'w+')
 
str = ""
while str != "exit\n"
 str = gets
 f.write(str)
end
 
f.close

دقیقا با این کد میتوانید هر چند خط که دلتان خواست، تایپ کرده سپس تایپ کنید exit و در آخر نتیجه را در پوشه ای که کد را اجرا کرده اید، مشاهده فرمایید.

در این مطلب سعی بر آن بود تا پایه ای ترین روش برای کار با فایل ها را مرور کنیم، برای اطلاعات بیشتر در مورد این کلاس، میتوانید راهنمای رسمی آن در وبگاه روبی را مطالعه کنید.

درآمدی بر Active Record


Active Record یک جم برای ارتباط سازمان دیده با دیتابیس بوده که توسط Rails تنظیم و فراخوانی میشود. این یک آشنایی با Active Record است و دانش SQL و Rails تا حدئ توصیه میشود هرچند نیازی به این دانش برای درک این مقاله نیست.

برای استفاده ابتدایی از ActiveRecord باید سه بخش از آن‌ را بشناسیم.

  1. Migration & Schema System (که به ظاهر دیتابیس شکل میدهد)
  2. CRUD Operations (که وظیفه ساختن، پیدا کردن، حذف کردن و تغییر دادن یک تیکه اطلاعات را به عهده دارد)
  3. Query Interface (که وظیفه پیدا کردن و رابطه برقرار کردن بین اطلاعات را به عهده دارد)

تنظیمات اولیه

میتوانید ActiveRecord را به دیتابیس‌هایی‌ مانند PostgreSQL, MySQL و SQLite متصل کنید. در این مقاله ما SQLite را انتخاب می‌کنیم به دلیل سادگی‌.

درون Gemfile می‌نویسیم

gem "sqlite3"

 

درون config/database.yml می‌نویسیم

 

development:
  adapter: sqlite3
  database: db/db_dev_db.sqlite3
  pool: 5
  timeout: 5000

 

بعد اجرا می‌کنیم

rake db:setup

 

Migration & Schema System

هر دیتابیس ساختار اطلاعات قابل ذخیره را توسط قواعد خشک و دقیق به نام اسکیما تعیین می‌کند. به طور مثال تعیین می‌کنیم که جدولی‌ از کاربران داریم و هر کاربر یک email از گونه String دارد.

Active Record Migrations به ما این اجازه رو میدن که Schema اطلاعاتمون رو کم کم و طی‌ زمان بسازیم. به این معنی‌ که در آینده میتونیم این Schema را تغییر بدیم.

برای شروع جدول کاربران را میسازیم. اول باید یک Migration جدید بسازیم


rails generate migration create_users_table

به این ترتیب که rails generate migration دستور بوده و باقی نام Migration است.

درون db/migrations/0000_create_users_table.rb خواهیم داشت:

class CreateUsersTable < ActiveRecord::Migration
  def change
    create_table :users do |t|
      t.string :email
      t.string :name
      t.timestamps
    end
  end
end

 

که دستور create_table جدولی‌ به نامه users می‌سازد و دستور t.string یک field به نامه email خواهد سخت.

حالا Migration را اجرا می‌کنیم.

rake db:migrate

 

هم‌اکنون دیتابیس ما ظاهری که Active Record انتظار دارد را دنبال می‌کند. پس شروع می‌کنیم به ساخت یک Active Record Model که با این جدول کاربران صحبت کند.

درون /app/models/user.rb می‌نویسیم.

class User < ActiveRecord::Base
end

 

و وارد کنسول Rails می‌شویم تا با Model جدیدمان کمی‌ کار کنیم.

bundle exec rails console -s

درون کنسول می‌نویسیم:

 

User.create first_name: "pooyan", last_name: "khosravi", email: "pekhee at gmail dot com"

این دستور یک کاربر برای ما سخته و شماره کاربری آن‌ را برمی‌گرداند. میتوانیم از دیتابیس آخرین کاربر را بگیریم.

User.last

روبی برای سی شارپ کارها

با سلام خدمت شما دوستان عزیزم.مدتی هست که توفیق اجباری شده سی شارپ یاد گرفتم. دو کلاس Console و Convert در این زبان شدیدا باعث علاقه مند شدن من به این زبان شدن. با خودم تصمیم گرفتم این دو کلاس رو به روبی بیارم. در واقع، خواستم یک اسکریپت کوچیک بنویسم تا هم خودم روبی رو بهتر و بیشتر یاد بگیرم، هم این که به دوستان سی شارپ کار که میخوان روبی رو یاد بگیرن، کمک کنم! خیلی خوب، بریم سراغ این که این اسکریپت رو چه طور استفاده کنیم؟

دریافت از گیتهاب

خیلی ساده، اول git رو نصب کنید و سپس مخزن من رو کلون کنید :

git clone https://github.com/prp-e/rubysharp

 

استفاده از روبی شارپ

روبی شارپ صرفا یک اسکریپت هست، کنار اسکریپت اصلی کپی کنید و بعد با استفاده از فایل README موجود (که گیتهاب هم نشونش میده!) ، کد نویسی کنید.

یک برنامه ساده در روبی شارپ

#!/usr/bin/ruby
 
load 'rubysharp.rb'
 
prompt = Console.Wrtie('Enter your age: ')
 
print prompt
 
age = Convert.ToInt(Console.Read())
 
age = age * 356
 
print Console.WriteLine("You lived #{age} days")