ruby notes(4)

  • Ruby calls serialization marshaling. Saving an object and some or all of its components is done using the method Marshal.dump. Later on you can reconstitute the object using Marshal.load
  • In Ruby, regular expressions are objects (of type Regexp) and can be manipulated as such. // is a regular expression and an instance of the Regexpclass, as shown below:
    //.class    # Regexp
  • In Ruby, classes are never closed: you can always add methods to an existing class.
  • In Ruby, a class can only inherit from a single other class.
  • Use require_relative (only works for Ruby 1.9) when the location of the file we’re loading is relative to the file we’re loading it from –  both in the same directory
  • if an object fails to find any such method, it raises a NoMethodError exception – unless you have provided the object with a method called method_missing
  • Blocks are not objects, but they can be converted into objects of class Proc.
    1. use procs as parameter (method cannot be used as parameters)
    def some_mtd some_proc
    puts ‘Start of mtd’
    some_proc.call
    puts ‘End of mtd’
    endsay = lambda do
    puts ‘Hello’
    endsome_mtd say

    The output is:

    Start of mtd
    Hello
    End of mtd
    1. Here’s another example of passing arguments using lambda.
    a_Block = lambda { |x| “Hello #{x}!” }
    puts a_Block.call ‘World’ => Hello World!
  • symbols are more efficient than strings. Two strings with the same contents are two different objects (different object_id), but for any given name there is only one Symbol object. This can save both time and memory.
  •  h = {:nickname => ‘IndianGuru’, :language => ‘Marathi’, :lastname => ‘Talim’}
    puts h

    The output is:

    {:nickname=>”IndianGuru”, :language=>”Marathi”, :lastname=>”Talim”}

    Another way (using name: value pairs to create a hash if the keys are symbols) of doing the same thing is

    h = {nickname: ‘IndianGuru’, language: ‘Marathi’, lastname: ‘Talim’}
    puts h

    The output is:

    {:nickname=>”IndianGuru”, :language=>”Marathi”, :lastname=>”Talim”}

    An exception to the shorter {symbol: value} syntax is when you would like to use a numeric key:

    hash = {1: ‘one’} # will not work
    hash = {1 => ‘one’} # will work
Advertisements

ruby notes(3)

  • Array
  1. # a trailing comma is ignored
    name = [‘Satish’, ‘Talim’, ‘Ruby’, ‘Java’,]
  2. an example of returning an array

def mtdarry(num)
square = num * num
return num, square if num > 5
end

# using parallel assignment to collect the return value
num, square = mtdarry (6)
puts num  => 6
puts square => 36

  • Array and range (a sequence)
    [“a”, “b”]===”a”  => false
    (‘a’..’b’) === ‘a’  => true #see if some value falls in the interval represented by the range
  • An environment variable is a link between our program and the outside world. You can access operating system environment variables using the predefined variable ENV. ENVis simply a hash.

ENV.each {|k,v| puts “#{k}: #{v}”}

  • Library GetoptLong

    Class GetoptLong supports command-line option parsing. Options may be a minus sign (-) followed by a single character, or two minus signs (–) followed by a name (a long option). Options may be given in any order. A single internal option may have multiple external representations. For example, the option to control verbose output could be any of -v, –verbose, or –details. Some options may also take an associated value. Each internal option is passed to GetoptLong as an array, containing strings representing the option’s external forms and a flag. The flag specifies how GetoptLong is to associate an argument with the option (NO_ARGUMENT, REQUIRED_ARGUMENT, or OPTIONAL_ARGUMENT).

    Suppose I want to call a Ruby program as:

    ruby tsftpc.rb -h ftp.ibiblio.org -n 21 -u anonymous -p s@s.com

    Here’s the code to do so:

    1. require ‘getoptlong’
    2. unless ARGV.length == 4
    3.   puts “Usage: ruby tsftpc.rb -h ftp_site_url -n port_no -u user_name -p password”
    4.   exit
    5. end
    6. host_name = port_no = user_name = password = ”
    7. # specify the options we accept and initialize
    8. # the option parser
    9. opts = GetoptLong.new(
    10. [ “–hostname”, “-h”, GetoptLong::REQUIRED_ARGUMENT ],
    11. [ “–port”, “-n”, GetoptLong::REQUIRED_ARGUMENT ],
    12. [ “–username”, “-u”, GetoptLong::REQUIRED_ARGUMENT ],
    13. [ “–pass”, “-p”, GetoptLong::REQUIRED_ARGUMENT ]
    14. )
    15. # process the parsed options
    16. opts.each do |opt, arg|
    17.   case opt
    18.     when ‘–hostname’
    19.       host_name = arg
    20.     when ‘–port’
    21.       port_no = arg
    22.     when ‘–username’
    23.       user_name = arg
    24.     when ‘–pass’
    25.       password = arg
    26.   end
    27. end
  • Ruby automatically places any parameters that are appended to the command line when you launch your Ruby program into a special array called ARGV. If your program tmp.rb is:
    f = ARGV[0]
    puts f

    You can execute this program from the command line as:

    ruby tmp.rb 23

    The program should display 23.

  • a=nil || “hi”
    a=> “hi”
    a=nil or “hi”
    a => nil

the reason is that the predence from high to low is ||, =, or

  • Ruby lets you have a comma-separated list of rvalues. Once Ruby sees more than one rvalue in an assignment, the rules of parallel assignmentcome into play. First, all the rvalues evaluated, left to right, and collected into an array (unless they are already an array). This array will be the eventual value returned by the overall assignment. Next, the left hand side (lhs) is inspected. If it contains a single element, the array is assigned to that element.
    a = 1, 2, 3, 4 # => a == [1, 2, 3, 4]
    b = [1, 2, 3, 4] # => b == [1, 2, 3, 4]

    If the lhs contains a comma, Ruby matches values on the rhs against successive elements on the lhs. Excess elements are discarded.

    a, b = 1, 2, 3, 4 # => a == 1, b == 2
    c, = 1, 2, 3, 4 # => c == 1

ruby notes (2)

  • The Ruby ri tool is used to view the Ruby documentation off-line. Open a command window and invoke ri followed by the name of a Ruby class, module or method.

ri Array
ri Array.sort
ri Hash#each
ri Math::sqrt

  • double quoted string does two more thing than single-quoted string:

first, it looks for substitutions – sequences that start with a backslash character – and replaces them with some binary value. second, expression interpolation

a=”hi”
=> “hi”
irb(main):002:0> puts “#{a}”
hi
=> nil
irb(main):003:0> puts ‘#{a}’
#{a}
=> nil

  • block
  • def call_block
    puts ‘Start of method’
    yield # you can call the block using the yield keyword
    yield
    puts ‘End of method’
    end
    # Code blocks may appear only in the source adjacent to a method call
    call_block {puts ‘In the block’}The output is:

    1. Start of method
    2. In the block
    3. In the block
    4. End of method

    If you provide a code block when you call a method, then inside the method, you can yield control to that code block – suspend execution of the method; execute the code in the block; and return control to the method body, right after the call to yield. If no code block is passed, Ruby raises an exception:

    no block given (LocalJumpError)

    You can provide parameters to the call to yield: these will be passed to the block. Within the block, you list the names of the arguments to receive the parameters between vertical bars (|).

    1. def call_block
    2.   yield(‘hello’, 99)
    3. end
    4. call_block {|str, num| puts str + ‘ ‘ + num.to_s}

    The output is:

    1. >ruby p023codeblock2.rb
    2. hello 99
    3. >Exit code: 0

    Note that the code in the block is not executed at the time it is encountered by the Ruby interpreter. Instead, Ruby remembers the context in which the block appears and then enters the method.

    A code block’s return value (like that of a method) is the value of the last expression evaluated in the code block. This return value is made available inside the method; it comes through as the return value of yield.

    block_given? returns true if yield would execute a block in the current context. Refer to the following example:

    1. def try
    2.   if block_given?
    3.     yield
    4.   else
    5.     puts “no block”
    6.   end
    7. end
    8. try # => “no block”
    9. try { puts “hello” } # => “hello”
    10. try do puts “hello” end # => “hello”

    Block Variables

    Let us see what happens in the following example when a variable outside a block is x and a block parameter is also named x.

    1. x = 10
    2. 5.times do |x|
    3.   puts “x inside the block: #{x}”
    4. end
    5. puts “x outside the block: #{x}”

    The output is:

    1. x inside the block: 0
    2. x inside the block: 1
    3. x inside the block: 2
    4. x inside the block: 3
    5. x inside the block: 4
    6. x outside the block: 10

    You will observe that after the block has executed, x outside the block is the original x. Hence the block parameter x was local to the block.

    Next observe what happens to x in the following example:

    1. x = 10
    2. 5.times do |y|
    3.   x = y
    4.   puts “x inside the block: #{x}”
    5. end
    6. puts “x outside the block: #{x}”

    The output is:

    1. x inside the block: 0
    2. x inside the block: 1
    3. x inside the block: 2
    4. x inside the block: 3
    5. x inside the block: 4
    6. x outside the block: 4

    Since x is not a block parameter here, the variable x is the same inside and outside the block.

    In Ruby 1.9, blocks introduce their own scope for the block parameters only. This is illustrated by the following example:

    1. x = 10
    2. 5.times do |y; x|
    3.   x = y
    4.   puts “x inside the block: #{x}”
    5. end
    6. puts “x outside the block: #{x}”

    The output is:

    1. x inside the block: 0
    2. x inside the block: 1
    3. x inside the block: 2
    4. x inside the block: 3
    5. x inside the block: 4
    6. x outside the block: 10

    In the above block, a new feature is being used: block local variable. In short, block local variables shield a block from manipulating variables outside of its scope. This prevents a block from unintentionally clobbering any variables outside its scope. If you don’t want to clobber variables, use block local variables for the variables your block creates.

    The syntax for a block local variable is simple. Put a semicolon after the normal block parameter list, then list the variable you want as block local variables. For example, if the block takes two variables a and b, and uses to local variables x and y, the parameter list would look like this: |a,b; x,y|.

copy on write

  • when a string is created by assignment, the memory is not assigned yet, it uses the existing resource address or pointer
  • when the string is changed, then the memory is assigned
  • this is lazy way
  • example
    std::string x("Hello");
    
    std::string y = x;  // x and y use the same buffer
    
    y += ", World!";    // now y uses a different buffer
                        // x still uses the same old buffer

ruby notes (1)

  • everything is an object
  • puts = put string
  • Java and C programmers – no need to write a main method/function
  • String literals are sequences of characters between single or double quotation marks. I am using single quotes around Hello. ‘ is more efficient than ” for constant string
  • Ruby is an interpreted language, so you don’t have to recompile to execute the program written in Ruby
  • The Ruby coding convention states that file/directory name is lower case of class/module name with .rb extension. For example, Foo class has name foo.rb
  • Multiple statements on one line must be separated by semicolons, but they are not required at the end of a line;
  • If a line ends with a backslash (\), the linefeed following it is ignored; this allows you to have a single logical line that spans several lines
  • everything is true except the reserved words false and nil
  • An integer literal is simply a sequence of digits eg. 0, 123, 123456789. Underscores may be inserted into integer literals (though not at the beginning or end), and this feature is sometimes used as a thousands separator eg. 1_000_000_000.
  • The increment and decrement operators (++ and – -) are not available in Ruby, neither in “pre” nor “post” forms. However, do note that the += and -= are available.
  • some operators like =,>=, <=, +, – , <<, >> is a kind of syntactic sugar (more on this later) – where something looks like an operator but is a method call.
  • Both or and || return their first argument unless it is false, in which case they evaluate and return their second argument. The only difference between or and || is their precedence. || has a higher precedence than or
  • “and” and “or” has a lower precedence than the assignment too, so we can write

if a = f(x) and b = f(y) and c = f(z) then d = g(a,b,c) end

which computes the value of d unless any of the values f(x),f(y),f(z) is false

  • use back-tick (`) in puts, as puts `dir` will show the directory of current dir
  • Every class or module definition block (class, module) has its own local scope, even nested class/module definition blocks.
  • Class variables are rarely used in Ruby programs.
  • A constant name starts with an uppercase letter followed by name characters. Class names and module names are constants
  • ruby is dynamic, fixed type is not required for a variable

x = 7           # integer

x = “house”  # string

  • FTE=full time employee
  • json string is a string, so it cannot be nil.

“null”.to_json
=> “\”null\””
nil.to_json
=> “null”

  • ruby allow us to write functions that can accept variable number of parameters
def foo(*my_string)
my_string.inspect
end
puts foo(‘hello’,’world’)
puts foo()

The asterisk (called the splat argument) is actually taking all arguments you send to the method and assigning them to an array named my_string. As you can see, by making use of the asterisk, we’re even able to pass in zero arguments. The code above will result in the Array [‘hello’, ‘world’] written in the first method call and an empty Array being written on the second call, as you can see in the following output:

[“hello”, “world”]
[ ]
  • the parameters passed by reference/address, everything is reference but not the objects themselves

# examples
def mymethod a
a.upcase
end
mystr = “abc”
mymethod(mystr) => “ABC”
mystr => “abc”

———————————
def mymethod2 b
b.upcase!
end
mymethod2(mystr) => “ABC”
mystr => “ABC”
  • Ruby methods that modify an object in-place and end in an exclamation mark are known as bang methods. Examples of such pairs of methods include sort/sort! for arrays, upcase/upcase! for strings, chomp/chomp! for strings, and reverse/reverse! for strings and arrays. In each case, if you call the non-bang version of the method on the object, you get a new object. If you call the bang version, you operate in-place on the same object.