ارائه ای که پیش رو دارید معرفی و آشنایی با زبان Ruby (روبی) می باشد.
در واقع معرفی زبان Ruby به عنوان یک زبان قدرتمند و در عین حال ساده و جذاب به خوانندگانی که با دنیای وسیع زبانهای برنامه نویسی تا حدی آشنا هستند و مایلند زبانهای جدید و نو را فرا بگیرند و گستره دانش خود در این زمینه را افزایش دهند؛ این معرفی می تواند شروع خوبی برای این دسته از افراد باشد.
همینطور برای آن دسته از برنامه نویسان تازه کار که از بسیاری از پیچیدگی ها و دردسرهای زبانهای معمول (Perl,PHP,Python,…) ناراضی هستند، زبان Ruby می تواند گزینه مناسبی برای یادگیری و استفاده باشد.
و البته برنامه نویسان حرفه ای که همواره به دنبال یادگیری زبانهای ابزارها، روشها و زبانهای جدید هستند تا با ترکیبی از ابزارهایی که دارند با دست بازتری نسبت به مسائل مختلف نگاه کنند.
در این ارائه، سعی شده است نگاهی سریع و اجمالی به :
تاریخچه زبان Ruby
Ruby چیست
چرا از Ruby استفاده کنیم
گرامر و syntax زبان Ruby
انداخته شود.
تاریخچه
زبان Ruby توسط آقای یوکی هیرو ماتسوموتو معروف به Matz سال 1995 بطور رسمی به دنیا آمد.
شروع کار این پروژه در سال 1993 بود با این ایده که ترکیبی از ویژگیهای زبانهای برنامه نویسی موجود در بازار را یکجا جمع کند.
در واقع Ruby زبان خیلی جدیدی نیست، بلکه ترکیبی از ویژگیهای خوب زبانهای دیگر مانند Perl , Python , Smalltalk هست؛ آقای matz دلش می خواست تمام این خوبیها رو یکجا داشته باشد.
دو سال بعد یعنی سال 2005 آقای matz توانست اولین نسخه این زبان رو تحت GPL License بصورت Public در آورد و این چنین شد که یک زبان دیگر هم به جمع خانواده بزرگ اپن سورس پیوست.
زبان Ruby از همان ابتدا مورد استقبال چشم گیری قرار گرفت و کماکان این میل ادامه دارد؛ بطوریکه در حال حاضر در ژاپن و بسیاری از کشورهای دیگر توانایی رقابت با زبان Python را دارد.
زبان Ruby بیشتر خصوصیات خودش رو از زبانهای قدرمتند Perl, Smalltalk, python گرفته است، منتهی بسیاری از پیچیدگیهای این زبانها (مخصوصا Perl) را در خود ساده کرده است و از این لحاظ به Better Perl یا پرل بهتر (پرل بهتر شده) نیز معروف است.
زیبایی زبان Ruby هم در همین دو کلمه خلاصه می شود :
سادگی ، قدرت.
اما زبان Ruby چیست و دلیل این همه محبوبیت برای چیست؟
زبان Ruby یک زبان تفسیری (Scripting Language) است که نیاز به کامپایل ندارد و فقط تفسیر می شود.
Ruby، یک زبان OO (Object Oriented) خالص هست.
ویژگیهای Ruby در یک نگاه :
یک زبان سطح بالاست.
زبانی با قابلیت OO خالص است؛ با همه چیز در این زبان بصورت آبجکت برخورد می شود.
زبانی تفسیری است.
روی فریم ورکهای مختلف قابل اجراست.
یادگیری این زبان ساده است.
روی سکوهای مختلف (مثل ویندوز و یونیکس و مکینتاش) قابل اجراست.
نوع آبجکتها در زمان اجرا تعریف می شوند.
همه چیز در Ruby، Object (شیئ) هست.
برای مثال اعداد (1و2و3و4و...) در Ruby شیئ هستند، کرکترها، شیئ هستند، متغیرها شیئ هستند و ...
.
مثلا عدد 4 ، شیئی از کلاس FixNum و عدد 4.5 شیئی از کلاس Float و کرکتر 'c' شیئی از کلاس String و رشته ABCD هم شیئی از کلاس String می باشد.
در Ruby ما تعریف متغیر نداریم.متغیرها در Runtime تعریف می شوند.
برای مثال:
اگر مقدار o=65 قرار دهیم ، با اینکار ، o را از نوع عددی (شیئی از کلاس FixNum) تعریف کرده ایم؛ و یا o=ABC ،o شیئی از نوع String تعریف می شود.
در Ruby به این متغیرها هم آبجکت می گوییم.
ابتدا برای ورود به محیط (کنسول) interactive زبان تفسیری Ruby (در صورتی که بسته نرم افزاری آن را نصب کرده باشید) irb را تایپ کنید.
شما وارد محیطی می شوید که می توانید مستقیما و بدون نیاز به هیچ ابزار اضافی کدهای خود را بنویسید (البته تا حدی و تنها برای تست عملکرد ها) و جواب بگیرید.
ابتدا برای ورود به محیط (کنسول) interactive زبان تفسیری Ruby (در صورتی که بسته نرم افزاری آن را نصب کرده باشید) irb را تایپ کنید.
شما وارد محیطی می شوید که می توانید مستقیما و بدون نیاز به هیچ ابزار اضافی کدهای خود را بنویسید (البته تا حدی و تنها برای تست عملکرد ها) و جواب بگیرید.
برای دانستن کلاسی که یک ابجکت از آن ساخته شده است با کمک متد .Class از هر آبجکتی می توان این کار را انجام داد؛ ابتدا به مقداری دلخواه را به یک متغیر نسبت می دهیم و مفسر Ruby بر اساس نوع مقدار (بطور دقیقتر، نوع Expression، چون سمت راست می تواند یک Expression باشد که در نهایت به یک مقدار تبدیل خواهد شد) سمت راست تساوی ، نوع متغیر ذکر شده را تعیین می کند و به اینصورت، آبجکتی از نوع کلاس مربوطه می سازد : O = 65 O.class # FixNum O= 65.5 O.class # Float O= "ABC" O.class #String باز هم برای اینکه این موضوع (همه چیز در Ruby آبجکت است) را بیشتر نشان دهیم، با تایپ عبارت زیر در محیط irb می توانید به یقین برسید!
: 123.class # FixNum 123.567.class # Float 'ABC'.class # String همونطور که اشاره شد، Ruby قدرت Perl را دارد، اما به مراتب ساختاری ساده تر و روان تر دارد.
در قیاس با زبان Python هم می توان گفت که Ruby سادگی Python را به ارث برده است؛ چه سادگی یادگیری زبان و چه سادگی در کدنویسی.
همینطور در خود مبحث مهم کد نویسی، شما کدهای خوانا تری را نسبت به Perl می توانید با Ruby بنویسید؛ در Perl می توانید با 1 خط، کار 10 خطی که در JAVA می نویسید را بکنید؛ Ruby همین کار را با 5 خط (فرضاً) انجام می دهد که نتیجه حاصل، کدی خواناتر و روانتر و در عین حال کمتر (در مقایسه با JAVA) است.
چند کد نمونه دیگر در Ruby (ساختارهای کلی زبان) : Classic Hello world example: puts "Hello World!" Some basic Ruby code: # Everything, including a literal, is an object, so this works: -199.abs # 199 "ruby is cool".length # 12 "Rick".index("c") # 2 "Nice Day Isn't It?".downcase.split(//).sort.uniq.join # " '?acdeinsty" Conversions: puts 'What\'s your favorite number?' number = gets.chomp outputnumber = number.to_i + 1 puts outputnumber.to_s + ' is a bigger and better favorite number.' Collections Constructing and using an array: a = [1, 'hi', 3.14, 1, 2, [4, 5]] a[2] # 3.14 a.reverse # [[4, 5], 2, 1, 3.14, 'hi', 1] a.flatten.uniq # [1, 'hi', 3.14, 2, 4, 5] Constructing and using a hash: hash = { :water => 'wet', :fire => 'hot' } puts hash[:fire] # Prints: hot hash.each_pair do |key, value| # Or: hash.each do |key, value| puts "#{key} is #{value}" end # Prints: water is wet # fire is hot hash.delete_if {|key, value| key == :water} # Deletes :water => 'wet' Blocks and iterators The two syntaxes for creating a code block: { puts "Hello, World!" } # Note the { braces } do puts "Hello, World!" end Parameter-passing a block to be a closure: # In an object instance variable (denoted with '@'), remember a block.
def remember(&a_block) @block = a_block end # Invoke the above method, giving it a block that takes a name.
remember {|name| puts "Hello, #{name}!"} # When the time is right (for the object) -- call the closure!
@block.call("Jon") # => "Hello, Jon!" Returning closures from a method: def create_set_and_get(initial_value=0) # Note the default value of 0 closure_value = initial_value return Proc.new {|x| closure_value = x}, Proc.new { closure_value } end setter, getter = create_set_and_get # ie.
returns two values setter.call(21) getter.call # => 21 Yielding the flow of program control to a block which was provided at calling time: def use_hello yield "hello" end # Invoke the above method, passing it a block.
use_hello {|string| puts string} # => 'hello' Iterating over enumerations and arrays using blocks: array = [1, 'hi', 3.14] array.each { |item| puts item } # => 1 # => 'hi' # => 3.14 array.each_index { |index| puts index.to_s + ": " + array[index] } # => 0: one # => 1: two # => 2: three (3..6).each { |num| puts num } # => 3 # => 4 # => 5 # => 6 A method such as inject() can accept both a parameter and a block.
Inject iterates over each member of a list, performing some function on while retaining an aggregate.
This is analogous to the fold1function in functional programming languages.
For example: [1,3,5].inject(10) {|sum, element| sum + element} # => 19 On the first pass, the block receives 10 (the argument to inject) as sum, and 1 (the first element of the array) as element, This returns 11.
11 then becomes sum on the next pass, which is added to 3 to get 14.
14 is then added to 5, to finally return 19.
Blocks work with many built-in methods: File.open('file.txt', 'w') do |file| # 'w' denotes "write mode".
file.puts 'Wrote some text.' end # File is automatically closed here File.readlines('file.txt').each do |line| puts line end # => Wrote some text.
Using an enumeration and a block to square the numbers 1 to 10: (1..10).collect {|x| x*x} # => [1, 4, 9, 16, 25, 36, 49, 64, 81, 100] Classes The following code defines a class named Person.
In addition to 'initialize', the usual constructor to create new objects, it has two methods: one to override the comparison operator (so Array#sort can sort by age) and the other to override the to_s method (so Kernel#puts can format its output).
Here, "attr_reader" is an example of metaprogramming in Ruby: "attr_accessor" defines getter and setter methods of instance variables, "attr_reader" only getter methods.
Also, the last evaluated statement in a method is its return value, allowing the omission of an explicit 'return'.
class Person def initialize(name, age) @name, @age = name, age end def (person) # Comparison operator for sorting @age person.age end def to_s "#@name (#@age)" end attr_reader :name, :age end group = [ Person.new("Jon", 20), Person.new("Marcus", 63), Person.new("Ash", 16) ] puts group.sort.reverse The above prints three names in reverse age order: Marcus (63) Jon (20) Ash (16) Exceptions An exception is raised with a raise call: raise An optional message can be added to the exception: raise "This is a message" You can also specify which type of exception you want to raise: raise ArgumentError, "Illegal arguments!" Alternatively, you can pass an exception instance to the raise method: raise ArgumentError.new( "Illegal arguments!" ) This last constuct is useful when you need to raise a custom exception class featuring a constructor which takes more than one argument: class ParseError def initialize input, line, pos super "Could not parse '#{input}' at line #{line}, position #{pos}" end end raise ParseError.new( "Foo", 3, 9 ) Exceptions are handled by the rescue clause.
Such a clause can catch exceptions that inherit from StandardError: begin # Do something rescue # Handle exception end Note that it is a common mistake to attempt to catch all exceptions with a simple rescue clause.
To catch all exceptions one must write: begin # Do something rescue Exception # don't write just rescue -- this only catches StandardError, a subclass of Exception # Handle exception end Or catch particular exceptions: begin # ...
rescue RuntimeError # handling end It is also possible to specify that the exception object be made available to the handler clause: begin # ...
rescue RuntimeError => e # handling, possibly involving e, such as "print e.to_s" end Alternatively, the most recent exception is stored in the magic global $!.
You can also catch several exceptions: begin # ...
rescue RuntimeError, Timeout::Error => e # handling, possibly involving e end Or catch an array of exceptions: array_of_exceptions = [RuntimeError, Timeout::Error] begin # ...
rescue *array_of_exceptions => e # handling, possibly involving e end منابع : Ruby Home Page http://www.ruby-lang.org/en/ Wiki http://en.wikipedia.org/ Programming Ruby http://www.rubycentral.com/book/