Disclaimer: I don't consider myself an expert of Ruby. I am an eternal student. But, what I describe here should be basic enough to get people going and hopefully be a reference site. I also assume audience has some prior programming knowledge.
Mac Users
Best way is to use RVM to install Ruby. If you need to specify Ruby version
number, do so by adding the version like this: --ruby=1.9.3
.
\curl -sSL https://get.rvm.io | bash -s stable --ruby=1.9.3
Windows Users
http://rubyinstaller.org/downloads/
This is your best friend. Use it to test and try different things. When you develop in Ruby on Rails, rails console will give you the same feel and it will also give you access to all classes in your code.
$ irb
1.9.3-p194 :001 > puts "Hello World"
Hello World
=> nil
https://github.com/styleguide/ruby
- Use came case for class names
- Use snake case for method and variable names
class RubyClassName
def this_is_method_name
variable_name = "whatever"
end
end
- Write expressive method names (Rubyist should be able to get a sense of what methods do without extensive documentation)
# Bad
def number
end
# Good
def get_squared_number
end
- Use
?
at the end of method if it returns truthy or falsy value
def is_even?(num)
num % 2 == 0
end
- Ruby method return whatever was evaluated last, so for simple method, don't use
return
keyword.
# Bad
def double_the_num(num)
product = num**2
return product
end
# Good
def double_the_num(num)
num**2
end
- Use
||=
to check for nil value and initialize a variable
# Bad
a = "something" if a.nil?
# Good
a ||= "something"
- Don't use
===
for conditions or to check types.===
is used for case/switch statement.
Literally, everything.
https://www.youtube.com/watch?v=F9GVKxSiQVM
$ irb
1.9.3-p194 :002 > "string".class
=> String
1.9.3-p194 :003 > 1.class
=> Fixnum
1.9.3-p194 :004 > 1.5.class
=> Float
1.9.3-p194 :005 > [1,2,3].class
=> Array
1.9.3-p194 :006 > {}.class
=> Hash
1.9.3-p194 :013 > String.superclass
=> Object
1.9.3-p194 :014 > Object.superclass
=> BasicObject
1.9.3-p194 :015 > BasicObject.superclass
=> nil
1.9.3-p194 :016 > nil.class
=> NilClass
Ruby variable names do not need any keyword prefix.
variable = "normal variable"
Except the following cases:
$variable = "global variable"
: Global variable
@@variable = "class variable"
: Class variable
@variable = "instance variable"
: Instance variable
VARIABLE = "constants"
: Constant variable
puts
adds a carriage return at the endprint
does not add a carriage return at the end"#{}"
means evaluate what's inside{}
. It only works with double-quotes. It doesn't work with single-quotes.
1.9.3-p194 :051 > print "Hello World"
Hello World => nil
1.9.3-p194 :052 > puts "Hello World"
Hello World
=> nil
1.9.3-p194 :053 > a = "Hello World"
=> "Hello World"
1.9.3-p194 :054 > puts "#{a} is what I say"
Hello World is what I say
=> nil
1.9.3-p385 :027 > puts '#{a} is not what I say'
#{a} is not what I say
=> nil
1.9.3: http://www.ruby-doc.org/core-1.9.3/Array.html
2.1.1: http://www.ruby-doc.org/core-2.1.1/Array.html
Mutable and can contain different types of data.
1.9.3-p194 :017 > a = Array.new
=> []
1.9.3-p194 :019 > b = []
=> []
1.9.3-p194 :022 > b << "1"
=> ["1"]
1.9.3-p194 :023 > b << 2
=> ["1", 2]
1.9.3-p194 :024 > b.push(:c => "d")
=> ["1", 2, {:c=>"d"}]
1.9.3-p194 :028 > b << {:d => "e"}
=> ["1", 2, {:c=>"d"}, {:d=>"e"}]
1.9.3-p194 :029 > b.pop
=> {:d=>"e"}
1.9.3-p194 :030 > b
=> ["1", 2, {:c=>"d"}]
1.9.3-p194 :031 > b.length
=> 3
1.9.3-p194 :032 > b.first
=> "1"
1.9.3-p194 :033 > b.last
=> {:c=>"d"}
1.9.3-p194 :034 > b[0]
=> "1"
1.9.3-p194 :035 > b[-1]
=> {:c=>"d"}
1.9.3: http://www.ruby-doc.org/core-1.9.3/Hash.html
2.1.1: http://www.ruby-doc.org/core-2.1.1/Hash.html
=>
is called hash rocket.
1.9.3-p194 :036 > a = Hash.new
=> {}
1.9.3-p194 :037 > b = {}
=> {}
1.9.3-p194 :039 > c = Hash.new([])
=> {}
1.9.3-p194 :040 > a[:a]
=> nil
1.9.3-p194 :041 > a[:a] = "a"
=> "a"
1.9.3-p194 :042 > a
=> {:a=>"a"}
1.9.3-p194 :043 > b[:a] = "b"
=> nil
1.9.3-p194 :045 > c[:a]
=> []
1.9.3-p194 :047 > c.size
=> 0
1.9.3-p194 :048 > a.size
=> 1
1.9.3-p194 :049 > a[:a]
=> "a"
Creating same string creates new object each time, but symbol doesn't.
1.9.3-p385 :014 > a = "blah"
=> "blah"
1.9.3-p385 :015 > a.object_id
=> 70297014082880
1.9.3-p385 :016 > b = "blah"
=> "blah"
1.9.3-p385 :017 > b.object_id
=> 70297013950380
1.9.3-p385 :018 > a.object_id == b.object_id
=> false
1.9.3-p385 :019 > a == b
=> true
1.9.3-p385 :020 > c = :blah
=> :blah
1.9.3-p385 :021 > c.object_id
=> 667848
1.9.3-p385 :022 > d = :blah
=> :blah
1.9.3-p385 :023 > d.object_id
=> 667848
1.9.3-p385 :024 > c == d
=> true
1.9.3-p385 :025 > c.object_id == d.object_id
=> true
if condition_a
do_something
elsif condition_b
do_something_else
else
do_yet_another
end
But if you only care about one condition use single line.
do_something if condition_a
Don't use unless with else.
# Bad
unless condition_a
do_something
else
do_something_else
end
# Good
do_something_else unless condition_b
Enumerable, 1.9.3: http://ruby-doc.org/core-1.9.3/Enumerable.html
Enumerable, 2.1.1: http://ruby-doc.org/core-2.1.1/Enumerable.html
In Ruby, most iterations happen over a collection of elements and you pass block that will be iterated on each element. Enumerable mixin or module provides a lot more functionalities than standard Array/Hash methods. Enumerable methods work both on arrays and hashes.
Use do/end
if multiple lines are required. Use {}
for single line.
numbers = [1, 2, 3]
numbers.each do |num|
puts num**2
puts num
end
numbers.each { |num| puts num }
hash = {:a => "A", :b => "B"}
hash.each { |key, value| puts "#{hash[key]} = #{value}" }
Net::HTTP, 1.9.3: http://www.ruby-doc.org/stdlib-1.9.3/libdoc/net/http/rdoc/Net/HTTP.html
JSON, 1.9.3 : http://ruby-doc.org/stdlib-1.9.3/libdoc/json/rdoc/JSON.html
Net::HTTP, 2.1.1: http://www.ruby-doc.org/stdlib-2.1.1/libdoc/net/http/rdoc/Net/HTTP.html
JSON, 2.1.1 : http://ruby-doc.org/stdlib-2.1.1/libdoc/json/rdoc/JSON.html
Net::HTTP, URI, and JSON are part of stanard libraries in Ruby. To use them, you need to require
them first.
Examples can be found here: http://www.rubyinside.com/nethttp-cheat-sheet-2940.html
GET
1.9.3-p194 :055 > require 'json'
=> true
1.9.3-p194 :056 > require 'net/http'
=> true
1.9.3-p194 :057 > require 'uri'
=> false
1.9.3-p194 :065 > uri = URI.parse("http://www.google.com")
=> #<URI::HTTP:0x007fb80446efb0 URL:http://www.google.com>
1.9.3-p194 :066 > response = Net::HTTP.get_response(uri)
=> #<Net::HTTPOK 200 OK readbody=true>
1.9.3-p194 :067 > response.code
=> "200"
1.9.3-p194 :068 > response.body
# Buch of HTML codes
1.9.3-p194 :068 > JSON.parse(response.body)
# JSON data converted to hash if it contains JSON data
POST
Using form data is easy.
response = Net::HTTP.post_form(uri, {"q" => "My query", "per_page" => "50"})
Using JSON data in body requires more typing
uri = URI.parse('https://myapp.com/api/v1/resource')
req = Net::HTTP::Post.new(uri, initheader = {'Content-Type' =>'application/json'})
req.body = {param1: 'some value', param2: 'some other value'}.to_json
response = Net::HTTP.start(uri.hostname, uri.port) do |http|
http.request(req)
end
You can also use RestClient gem: https://github.com/rest-client/rest-client
1.9.3: http://ruby-doc.org/core-1.9.3/File.html
2.1.1: http://ruby-doc.org/core-2.1.1/File.html
Use abosolute path to read from file. You can also go each line by line as well. Refer to the links above.
> json = File.read("/pah/to/json/file.json")
> puts json
# output of file content
Just add absolute path to the ruby binary at the top of ruby script and make the script executable.
yangtheman:~/codes/ruby/practices$ whereis ruby
/usr/bin/ruby
yangtheman:~/codes/ruby/practices$ ruby -v
ruby 1.9.3p385 (2013-02-06 revision 39114) [x86_64-darwin12.2.1]
#!/usr/bin/ruby
puts "Hello World"
- Ruby has only single inheritance.
- Ruby class constructor method is called
initialize
. It gets called automatically when an instance of a class is created. - Use
attr_reader
to make an attribute readable. - Use
attr_writer
to make an attribute writable. - Use
attr_accessor
to make an attribute both readable/writable.
class SampleClass
attr_reader :length
def initialize(len = 10)
@length = len
end
end
sample = Sample.new
sample.length # will return 10
- Subclass can be created using
<
. - Use
super
method to access the same method in parent class.
class ChildClass < SampleClass
def initialize(len = 5)
super
end
end
child = ChildClass.new
child.length # will return 5
- Module serves two purposes: Namespacing and Mixin
- It cannot be instantiated.
- It can be included in a class to make the methods available to an instance or a class.
# Namespacing
Module TopName
class SomeClass
end
end
test = TopName::SomeClass.new
# Mixin
Module MoreArrayMethods
def some_method
end
end
Class Array
include MoreArrayMethods
end
class Hash
extend MoreArrayMethods
end
array = Array.new
array.some_method # instance method
Hash.some_method # class method
hash = Hash.new
hash.extend MoreArrayMethods
hash.some_method # instance method