مدیریت محتوا با Sinatra و Mongo – قسمت آخر

در قسمت دوم، یاد گرفتیم که چطور پیج هایی که ساختیم رو نمایش بدیم! در این قسمت، میخوایم مستقیما با دیتابیس وارد مذاکره بشیم! در واقع در این قسمت میخوایم به کاربر اجازه بدیم که خودش یک پیج ایجاد کنه. خیلی هم شیک و ساده. ابتدا این قسمت رو به main.rb اضافه کنید :

get '/pages/new' do
	@page = Page.new
	erb :new
end

در اینجا، گفته شده که یک صفحه به اسم new.erb خونده و نمایش داده بشه. علاوه بر اون، گفتیم که از کلاس Page هم یک شیء جدید برامون بسازه. حالا، فایل new.erb رو به این شکل ایجاد کنید :

<h1> New Page </h1>
 
<form action="/pages" method="post">
	<h2> Title: </h2>
	<input type="text" name="page[title]">
	<h2> Text: </h2>
	<textarea name="page[text]" cols="50" rows="5">
	</textarea>
	<br/>
	<input type="submit">
</form>

در اینجا یک فرم ایجاد کردیم که با متد POST کار میکنه. قبل تر، در مورد متد پست توضیح دادیم، و میتونید این مطلب رو در موردش بخونید تا درکش کنید!

بسیار خوب، الان برای این که برنامه ما درست و حسابی کار کنه، فقط نیاز داریم که با یک متد POST بهش بفهمونیم که اطلاعات رو توی دیتابیس بنویسه. و خب این قسمت رو به main.rb مون اضافه میکنیم :

post '/pages' do
	page = Page.create(params[:page])
	redirect to("/pages/#{page.id}")
end

خب، در اینجا میگیم که پیجی با پارامتر هایی که داده شده بساز، و بعدش برگرد به همون پیج. به همین سادگی!

جمع بندی

در کل این سه قسمت آموزش، یک CMS بسیار ساده ساختیم که یه ادیتور داشت و میتونست نوشته های ما رو توی یک دیتابیس ذخیره کنه و بعد به ما نشون بده. کل فایل main.rb ما به این شکل در اومد :

require 'sinatra'
require 'mongoid'
 
configure do
	Mongoid.load!("./database.yml")
end
 
class Page
	include Mongoid::Document 
	field :title, type: String
	field :text,  type: String
end
 
 
get '/pages' do
	@pages = Page.all
	@title = "Page List"
	erb :index
end
 
get '/pages/new' do
	@page = Page.new
	erb :new
end
 
post '/pages' do
	page = Page.create(params[:page])
	redirect to("/pages/#{page.id}")
end
 
get '/pages/:id' do
	@page = Page.find(params[:id])
	@title = @page.title
	erb :show
end

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

simple-cms/
├── database.yml
├── main.rb
├── README.md
└── views
    ├── index.erb
    ├── new.erb
    └── show.erb

با استفاده از چنین الگویی، شما قادرید که برنامه های واقعی تری بنویسید و از اونها در دنیای واقعی استفاده کنید. در قسمت اول ذکر شد که این CMS بدرد وبلاگ و وبسایت و … نمیخوره. دلیلشم مشخصه! توی این برنامه هیچگونه پرمیشن و سشن و … ای رعایت نشده که بدونیم کدوم یوزر میتونه پیج ایجاد کنه کدوم نمیتونه و این قضایا. یعنی امنیت نداره کانتنتی که روی اون وبسایت تولید میشه. شما میتونید با خوندن داکیومنت در مورد session ها این مورد رو هم هندل کنید و CMS کامل تری بسازید!

موفق باشید :)

مدیریت محتوابا Sinatra و Mongo – قسمت دوم

در قسمت قبل، یاد گرفتیم که چگونه یک سیستم مدیریت محتوای کوچولو رو با پایگاه داده هاش، ایجاد کنیم. در این قسمت، نمایش محتوای پیج در لینک اختصاصی و همچنین نمایش لینک ها در صفحه اصلی رو بررسی میکنیم.

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

بسیار خوب، فایل index.erb که صفحات ما رو نشون میداد باز کنید، به این شکل تغییرش بدید :

<h1> Pages </h1>
<% if @pages.any? %>
<p>
<%  @pages.each do |page| %>
<a href="/pages/<%= page.id %>">
<h1><%= page.title %> </h1>
</a>
<p> <%= page.text %> </p>
<% end %>
</p>
<% else %>
<h1> No pages added! </h1>
<% end %>

دقت کردید؟ ما از id صفحات برای تولید لینک به اون ها استفاده میکنیم!

حالا بیاید کمی فکر کنیم، وقتی روی این لینک ها کلیک کنیم چه اتفاقی میفته؟ طبیعتا یه ارور ۴۰۴ به ما نشون داده میشه و به ما گفته میشه که صفحه یافت نشده. معمولا سیناترا به صورت پیشفرض یک راهنمایی کوچک هم میکنه که چه چیزی باید به فایل main.rb و … اضافه کنیم تا بتونیم نتیجه درستی بگیریم.

حالا برای این که لینک ها ما رو به جای درستی راهنمایی کنند، کافیه که فایل main.rb رو باز کنیم و این خطوط رو بهش اضافه کنیم :

get '/pages/:id' do
	@page = Page.find(params[:id])
	@title = @page.title
	erb :show
end

خب توی این کد، میگیم که پیج ها رو بر اساس id شون پیدا کنه، و تیتر صفحه رو هم تیتر پیج ایجاد شده بذاره. و در نهایت هم میگیم که ظاهر برنامه در show.erb هست. حالا، نیاز داریم که یک show.erb هم بنویسیم :

<h1><%= @page.title %> </h1>
<p>
<%= @page.text %>
</p>
<a href="/pages"> Back to main page </a>

اینجا، عنوان و متن صفحه رو نشون دادیم، به صفحه اصلی هم که لیست مطالبمون داخلش قرار داره هم لینک کردیم. در آموزش بعدی، سعی میکنیم یه ادیتور بسازیم و بتونیم یک صفحه جدید رو از طریق مرورگر، به CMSمون اضافه کنیم!

کتاب آموزش روبی (نسخه دوم)

در سال ۱۳۹۳ بود که نسخه اول کتاب آموزش روبی نگاشته و منتشر شد، اکنون، در روز ۲۸ شهریور ماه ۱۳۹۵ بعد از گذشت حدود دو سال، دومین نسخه از این کتاب عرضه می شود.

نسخه جدید کتاب علاوه بر این که با فرمت جدیدی نگاشته شده است، به صورت آنلاین (از آدرس : http://book.rubydev.ir ) نیز در دسترس است. همچنین سرفصلهای کتاب تغییر کرده و شکل و شمایل جدیدی به خود گرفته است. سرفصل های کتاب به این شکل هستند :

  • مقدمه
  • آشنایی با روبی
  • پایه ها و مقدمات
  • متغیر ها و انواع داده ها
  • آرایه ها و جداول درهم سازی
  • عملگرها
  • ساختارهای کنترلی
  • حلقه های تکرار
  • توابع
  • برنامه نویسی پیشرفته در روبی
  • برنامه نویسی شی گرا در روبی
  • برنامه نویسی کاربردی در روبی
  • یک پروژه نمونه

rubybookcover

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

لینک دریافت کتاب

 

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

عبارات با قاعده یا 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 های مختلف نمود.

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

 

استفاده از متد POST در سیناترا

فرمورک Sinatra یک میکروفرمورک وب است که اکثر کاربران و توسعه دهندگان روبی، با آن آشنایی دارند. برای شروع و ساخت پروژه هایی که زمان زیادی برایشان نداریم، بدون شک این فرمورک یکی از بهترین انتخاب هاست. در اکثر مثالهایی که در اینترنت موجود است، به گفتن متد get بسنده کرده اند. در حالی متد POST هم متد مهمی در فرمورک های وب به شمار می آید. در این آموزش، استفاده از متد post را بررسی میکنیم.

قدم های اولیه

ابتدا یک پوشه به اسم post-app ایجاد کرده، درون این پوشه پوشه دیگری با نام views ایجاد کنید. سپس در همان پوشه post-app فایل app.rb را نیز ایجاد نمایید. در واقع، این ها قدم های اولیه ما برای نوشتن یک برنامه در سیناتراست. درون پوشه views یک فایل با نام form.erb ایجاد کرده، آن را باز کنید و درونش این محتوا را کپی کنید :

<h3>Simple Form</h3>
<form action="/form" method="post">
  <input type="text" name="content">
  <input type="submit">
</form>

سپس به app.rb رفته، آن را باز کرده و این محتوا را درونش قرار دهید :

require 'sinatra'
 
get '/' do
 erb :form
end

اکنون چنانچه برنامه را اجرا کنید، متوجه خواهید شد که هرچه درون فرم بنویسید، طبیعتا باید به یکجا ارسال شود. اما کجا؟ اینجاست که ما متد POST را نیاز داریم.

اضافه کردن post به کد

همانطور که در کد form.erb مشاهده کردید، ما در قسمت action از آدرس form استفاده نمودیم و همچنین نام محتوای داخل فرم را content گذاشتیم. اکنون فایلی به نام content.erb در views ایجاد کرده، آن را باز کنید و محتوای درونش را به این شکل تغییر دهید :

<h2> You Said </h2> 
<h3> <%= params[:content] %> </h3>

سپس به فایل app.rb برگشته و این خطوط را به آن اضافه نمایید :

post '/form' do
 erb :content
end

و اکنون با اجرای برنامه، هرچه درون فرم طراحی شده بنویسید را در آدرس form مشاهده میکنید. با استفاده از متد post میتوانید اطلاعات را درون یک دیتابیس بنویسید و بیشتر استفاده آن نیز در این موارد است.

موفق باشید.

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

در آموزش پیشین ، در مورد تبدیل نوع کلاس ها و همچنین ارث بری به قدر کافی صحبت شد. در این آموزش، قصد داریم تا در مورد «سر بارگذاری عملگرها» یا 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

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

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

کار با کلاس 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 و در آخر نتیجه را در پوشه ای که کد را اجرا کرده اید، مشاهده فرمایید.

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

مدیریت جم های مورد نیاز با Bundler

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

require 'sinatra'
require 'highline/import'
require 'json/ext'

 

و در فایل راهنما، به کاربر برنامه می گوییم تا جم مورد نیاز را توسط دستور gem نصب نماید. اما، چرا جم ها را مستقل از کل سیستم روبی نصب نکنیم؟ تا فقط در دایرکتوری برنامه خودمان معتبر باشند، و کاربر دستورات کمتری را برای نصب جم های مورد نیاز وارد کند. برای این کار، از bundler استفاده میکنیم. (توجه کنید که هم دستور bundle و هم دستور bundler در واقع یکی هستند). برای این که از Bundle استفاده کنیم، نیاز داریم تا یک فایل به اسم Gemfile ایجاد کنیم. سپس درون جم فایل، باید این اطلاعات را وارد نماییم :

  1. سروری که جم ها روی آن قرار دارند
  2. نام جم ها
  3. نسخه مورد نظر جم های مورد نیاز

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

source 'https://rubygems.org'

 

به این شکل، Bundler میفهمد که ما از وبسایت rubygems بعنوان منبع جم ها باید استفاده کند. اکنون نیاز است تا جم های مورد نیاز را به Gemfile خود بدهیم. با فرض این که جم های سیناترا را نیاز داریم، در جم فایل چنین مینویسیم :

gem 'sinatra'
gem 'sinatra-assetpack'
gem 'tilt'
gem 'mongo'

 

خب، اکنون با اجرای دستور :

bundle install

جمهای مورد نیاز، در دایرکتوری برنامه ما نصب می شوند. اما هنوز یک مشکل داریم، برای مثال sinatra-assetpack ، با نسخه های ۲ به بعد tilt مشکل دارد، پس با این حساب باید نسخه این جم را پایین آوریم، پس در جم فایل این چنین تغییر ایجاد میکنیم :

gem 'sinatra'
gem 'sinatra-assetpack'
gem 'tilt', '1.4.1'
gem 'mongo'

با این کار، Bundler میفهمد که نسخه ۱.۴.۱ از جم tilt را باید نصب کند. اما اگر ندانید آخرین نسخه پایدار tilt چیست چطور؟  باید به شکل زیر عمل کنید :

gem 'sinatra'
gem 'sinatra-assetpack'
gem 'tilt', '< 2.0'
gem 'mongo'

به این شکل، bundler آخرین نسخه پایدار قبل از ۲.۰ را برای ما نصب میکند. در نهایت، جم فایل ما به این شکل در می آید :

source 'https://rubygems.org'
 
gem 'sinatra'
gem 'sinatra-assetpack'
gem 'tilt', '<2.0'
gem 'mongo'

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

شروع کار با کافی اسکریپت – توابع

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

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

func = () -> alert "Hello, World!"
 
func()

معادل این کد در جاوااسکریپت این چنین است :

var func;
 
func = function() {
  return alert("Hello, World!");
};
 
func();

کاربرد توابع void را در آموزش مربوط به کلاسها و شیء گرایی خواهیم دید.

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

square = (x) -> x ** 2

و معادل همین کد در جاوااسکریپت چنین است :

var square;
 
square = function(x) {
  return Math.pow(x, 2);
};

اما گاهی اوضاع این چنین نیست و مجبور خواهیم بود که از چندین عملیات در تابع استفاده کنیم. نمونه بارز این نوع توابع نیز تابعی است که ب.م.م دو عدد را حساب میکند. این تابع در کافی اسکریپت به شکل زیر پیاده سازی می شود.

gcd = (x, y) ->
      while y != 0
         remainder = x % y
         x = y
         y = remainder
      return x

معادل این تابع در جاوااسکریپت :

var gcd;
 
gcd = function(x, y) {
  var remainder;
  while (y !== 0) {
    remainder = x % y;
    x = y;
    y = remainder;
  }
  return x;
};

اینجا مجبور شدیم تا کلمه کلیدی return را مستقیما به کار ببریم. پیاده سازی توابع در کافی‌اسکریپت، بسیار ساده است. اکنون به مهم ترین بخش قضیه، یعنی توابع بازگشتی میرسیم. تابع بازگشتی، تابعی است که نتیجه جمله n ام آن به جمله n-1 ام وابسته باشد. نمونه خوب و کاربردی تابع بازگشتی هم تابع فاکتوریل است.

factorial = (x) -> 
          if x == 0
             return 1
          else
             return x * factorial(x-1)

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

معادل این کد در جاوااسکریپت :

var factorial;
 
factorial = function(x) {
  if (x === 0) {
    return 1;
  } else {
    return x * factorial(x - 1);
  }
};

بحث توابع، بحث جدی و بسیار مهمی در هر زبان برنامه نویسی است. در اینجا سعی شد تا به بهترین شکل، توابع بیان شوند. این بحث، آخرین بحث از سری مقالات «شروع به کار با کافی اسکریپت» بود و انشاء الله در آینده ای نزدیک، مباحث شی گرایی را آغاز خواهیم کرد.

موفق باشید.