CSC/ECE 517 Fall 2011/ch3 3a oe

From Expertiza_Wiki
Jump to navigation Jump to search

Ruby Introduction

Ruby is an interpreted, dynamically-typed, polymorphic, object-oriented programming language. The author, Yukuhiro "Matz" Matsumoto, describes it as blending aspects of Perl, Smalltalk, Eiffel, Ada, and Lisp. [1] As a result, it is very flexible language from top to bottom. It can be used as a procedural scripting language for rudimentary scripts, or as object oriented language.

Originally released in 1995, it gained widespread recognition a decade later with the availabiliy and widespread adoption of the web programming framework Ruby on Rails. [2]

Basic syntax

In comparison with some other object-oriented or procedural languages such as Java or C, Ruby has a flexible syntax. Many aspects of a statement that would be required in Java are optional in Ruby.

  • Semicolons at the end of each line are optional. They are generally used only when combining multiple statements on a single line.
  • A return statement at the end of a method is not necessary. If there is no return statement, the return value of the last executed statement is returned.
  • Method arguments. Methods can be created that will accept any number of arguments without using overloading in the conventional sense. Methods can be called with or without parentheses around arguments.
  • Variable types. Types for variables do not need to be declared in Ruby.

In other cases, where there may be only one way to write a statement in Java, for example, there may be nearly limitless ways to do so in Ruby. The programmer is allowed to determine which way works best for the situation at hand.

Control Strucures

There are some significant differences in control structures between Ruby and Java.

Blocks and closures

Loops and iterators

These constructs all achieve the same result of printing the nubmers 1 through 5. It is left up to the programmer to decide which method works the best for the particular situation.

for i in 1..5 do puts i.to_s; end
for i in [1,2,3,4,5] do puts i.to_s; end
(1..5).each { |i| puts i.to_s }
[1,2,3,4,5].each { |i| puts i.to_s }
1.upto(5) { |i| puts i.to_s }
1.step(5,1) { |i| puts i.to_s }

Object-Oriented principles

Everything is an object

In comparison with some other Object Oriented languages, Ruby is a very "pure" language, in that essentially everything is an object. There are no primitive types, and even numbers or literal strings are treated as objects and can have methods run on them.

5.times do puts "hello"; end
"hello".index('e')    ->returns 1

Unbounded polymorphism

Object types and classes are not checked by the compiler (there is no compiler!) or at runtime. An object's class does not matter as long as it contains all the instance methods and variables that are accessed. This is also known as "Duck Typing," a reference to the famous "Duck test": If it looks like a duck, swims like a duck, and quacks like a duck, then it probably is a duck.

Dynamic typing

Data types of objects are handled and checked at runtime, as opposed to a statically typed language where they are checked at compile time. In a statically typed language like Java, when you define an array, it must be an array containing elements all of the same type. In dynamically typed languages like Ruby, each element of an array can be any type.

Basic types/classes

Array

http://www.ruby-doc.org/core/Array.html

An array is an ordered one dimensional vector of objects. The objects in the vector are indexed with consecutive integers starting from zero. Any element in any array can be of any object type. An array is created as below:

@a1 = ['a', 2, :blah]
 or
@a2[0] = 'a'
@a2[1] = 2
@a2[2] = :blah

The individual elements are accessed as below:

@a[0]
--> 'a'

Unlike some other languages, arrays in Ruby are dynamically allocated and can shrink and grow as necessary. Array elements can be accessed by negative indices as well. An index of -1 will retrieve the ultimate element in the array; an index of -2 will retrieve the penultimate element, and so on. An undefined array element that is written to by index will be allocated and defined automatically, while an undefined element read by index will return nil. Therefore, there will never be an out of bounds error for an array in Ruby.

Examples of useful instance methods:

  • array.push(object): adds an element to the end of an array.,
  • array.pop adds or retrieves the last element to/from the front of any array.
  • array.unshift(object): adds an element to the front of an array.
  • array.shift: removes and returns the element to the front of the array.
  • array.each { |val| block }: iterator that executes the block once for each element in the array
  • array.length: returns the number of elements in the array
  • array.concat: Returns an array containing the array concatenated with another

Hash

http://www.ruby-doc.org/core/Hash.html

A hash is similar to an array, however it is not ordered and it is indexed by keys, which can be any object type. It functions as a mapping from the key to the value. An interesting point is that a hash could be treated just like an array, if all elements in the hash are indexed by integers.

A hash is defined as below:

@h1 = {'a' => 'foo', 2 => 'bar'}
 or
@h2['a'] = 'foo'
@h2[2] = 'bar'

Examples of useful instance methods:

  • hash.keys: returns an array populated with all the keys of the hash.
  • hash.values: returns an array populated with all the values of the hash. If both keys and values are retrieved without modifying the hash between, the keys and values will be in the same order.
  • array.each { |key,val| block }: iterator that executes the block once for each element in the hash


String

http://www.ruby-doc.org/core/String.html

A string is a sequence of bytes (Frequently characters.) It can be used to store data in any encoding: ASCII, unicode, or binary.

A string is defined as follows:

@s = "hello world"

Examples of useful instance methods:

  • string.length: returns the number of bytes in the string.
  • string.index(pattern) returns the index of the first occurence of a pattern or regular expression
  • string.sub(pattern, replacement): Substitutes the first occurrence of a substring or regular expression pattern with replacement.

Symbol

http://www.ruby-doc.org/core/Symbol.html

A symbol is similar to a string, with the exception that it is immutable - it cannot be changed once defined. Any reference to a particular symbol will refer to the same object for the entire time that a program is running. A symbol is defined as follows:

:Foo