cs498gpl:introduction_to_ruby
Table of Contents
Introduction to Ruby
"A Programmer's Best Friend"
Ruby
- Creator: Yukihiro Matsumoto
- Introduced: 1995
- Open source
- Installable package on many UNIX/Linux systems
- Windows installer obtainable from http://www.ruby-lang.org
- For macOS, installing Ruby through homebrew is recommended: https://www.ruby-lang.org/en/documentation/installation/#homebrew
- Can be used for tasks that other dynamic programming languages are used for.
- Initially gained a following due to the popularity of the Ruby on Rails web application framework.
-
- Used as a domain-specific language in Chef and Puppet.
- Popularity/Usage (Stack Overflow Developer Survey)
Ruby Online Resources
- http://www.ruby-lang.org - Official site
- http://www.ruby-doc.org/ - Official documentation site
- http://www.ruby-lang.org/en/documentation/ruby-from-other-languages/ - Coming to Ruby from other languages
- https://rubygems.org - The Ruby community’s gem hosting service
- Books:
- http://ruby-doc.org/docs/ProgrammingRuby/ - “Programming Ruby”
- http://www.techotopia.com/index.php/Ruby_Essentials - “Ruby Essentials”
- https://github.com/chriskempson/portable-humble-little-ruby-book - “Humble Little Ruby Book”
- https://nostarch.com/rubywizardry - “Ruby Wizardry (An Introduction to Programming for Kids)”
Ruby Execution
- Programs typically given .rb extension
- Executed with ruby prog.rb
- Or use shell script type line at top of Ruby script
- #!/path/to/ruby
- and make executable with chmod +x prog.rb
- Interactive shell by running irb
Ruby: Syntax summary
- A quick reference, in html
Ruby: What might be familiar
- indentation and whitespace generally not significant
- Perl-like “expression if bool-expr” and “expr unless bool-expr” can be used.
print
andputs
- print omits \n at end
- puts includes \n at end
Regular expressions
- Regular expressions are built-in (like Perl)
- Regexp objects can be built with
%r|regex|
%r
is one of several “Percent Strings” in Ruby.
mypattern = %r|[aeiou]|
- match with =~ or .match()
puts "String has vowels" if "This is a test" =~ /[aeiou]/ puts "String has vowels" if "This is a test".match("[aeiou]") puts "String has vowels" if "This is a test".match( mypattern ) x = "This is a test".match(/(\w+) (\w+)/) puts x[0] puts x[1] puts x[2]
- substitute with .sub (1 instance) or .gsub (global sub)
puts "foobar".sub('bar', 'foo') puts "this is a test".gsub('i', '') x = "This is a test" puts x.sub(/^../, 'Hello')
- Also see the Ruby string class' .scan() method.
- Complete documentation on Ruby regex handling is at https://ruby-doc.org/core-3.1.1/Regexp.html
- Includes options for multiline matching and other modifiers.
Arrays and hashes
- Ruby uses "arrays and hashes", like Perl:
x = [1, 2, 3, 4] # array called x x << 5 # adds 5 to array x x = { "a" => 1, "b" => 2 } # hash called x # Ruby-style iteration through hash: x.each { |key, value| puts "#{key} equals #{value}" } # The above uses a shorter version of the following 'do' block: x.each do |key, value| puts "#{key} equals #{value}" end
Ruby: What might not be familiar
Control structures
if bool-expr [then] body elsif bool-expr [then] body else body end while bool-expr [do] body end for name[, name]... in expr [do] body end
Variable interpolation
- Use #{varname} or #{expression}
x = 10 y = 20 z = "annoying" puts "#{x} + #{y} = #{x + y}" puts "This is so #{z.upcase}!" # also works # puts "This is so " + z.upcase + "!"
Multi-line strings
- Can create a multi-line string with the
%q
percent string- No variable interpolation can be done within
%q
.
x = %q{This is a test of the multi line capabilities}
- Variable interpolation can be done within
%Q
s = 'another' x = %Q{This is #{s} test of the multi line capabilities}
Ruby naming conventions
- Ruby enforces some naming conventions.
- If an identifier starts with a capital letter, it is a constant.
- Method names, however, are also allowed to start with capital letters.
- If it starts with a dollar sign ($), it is a global variable.
- such as the built-in $stdin global object
- See the cheatsheet for other global objects (a.k.a. Predefined Variables).
- If it starts with @, it is an instance or object variable.
- instance vars have scope within the current object
- If it starts with @@, it is a class variable.
- like
static
variables in Java - class vars have scope within the entire class
- Some other conventions
- Boolean methods end in ?
- Hash#has_key? ( key )
- Methods can be made to mutate their argument(s), by appending !
- Str#downcase!
mystring = "Are strings mutable?" mystring.downcase puts mystring + " No." mystring.downcase! puts "#{mystring} It Depends!"
Everything except nil and false considered true
# in Ruby, 0 is considered true. if 0 puts "0 is true" else puts "0 is false" end
Ruby-style iteration and blocks
# Preferred form some_list.each do |this_item| # some statements end # In Python: for this_item in some_list: # In Perl: foreach $this_item (some_list)
- The
do … end
section is called a block and can be shorted to an “inline” block using curly braces {}.- This is best used for short blocks.
some_list.each do |this_item| # some statements end some_list.each { |this_item| # some statements } # Example of an inline block
- The
with_index
method can be used witheach
to iterate through an array by index.- Similar to Python's
enumerate()
function
some_list.each.with_index do |item, item_index| # Sample statement to print numbered list of items: puts "#{item_index}. #{item}" end # Can also specify starting value of item_index: some_list.each.with_index(1) do |item, item_index| # Sample statement to print numbered list of items: puts "#{item_index}. #{item}" end
Functional ops using map and filter
- In the functional programming paradigm, the “map” and “filter” operations are important “higher-order” functions for processing collections of data.
- The “fold” (or “reduce”) operation is a third fundamental higher-order function.
- Ruby does not have list comprehensions like Python, but methods like
map
andfilter
may serve the same purpose as list comprehensions, i.e., create lists from lists.
- In Ruby, the
map
(orcollect
) method applies a given block to each item of an iterable (like an array) and returns a new array of the results that is the same size as the source iterable.
# Range of ints from 1 to 10 nums = 1..10 # Map applies a block to every element of an array # and returns a resulting array of the same size: nums.map do |num| num.to_s # returns string copy of num end # Assign result of map to an array: strnums = nums.map do |num| num.to_s end # Map an inline block and replace original Range object with an array: nums = nums.map { |num| num.to_s } # Replace original array contents with map!: nums.map! { |num| num.to_i } # Array of symbols: animals = [:mouse, :bat, :pangolin] # Map with array index included (index starts at 1): animals.map.with_index(1) { |name, index| "#{index}. #{name}" } # What is returned when a void function block is mapped? animals.map.with_index(1) { |name, index| puts "#{index}. #{name}" }
- The
filter
(orselect
) method applies a given block to each item of an iterable (like an array) and returns a new array containing all elements of the original iterable for which the given block returns true.
# Use %w percent string to create a list of strings: words = %w{You feel a whole lot more like you do now than you did when you used to} # Filter words in array that have length <= 3: words.filter do |word| word.length <= 3 # boolean block end # Shorter filter that modifies original words array: words.filter! { |word| word.length <= 3 }
Symbols
- Symbols, a feature of languages such as LISP
- begin with :
- don't contain values or objects, unlike variables
- can be considered literal constants that have no value
current_situation = :good puts "Everything is fine" if current_situation == :good puts "PANIC!" if current_situation == :bad # as opposed to current_situation = "good" puts "Everything is fine" if current_situation == "good" puts "PANIC!" if current_situation == "bad"
- Symbols often used in hash creation
person1 = { :name => "Fred", :age => 20, :gender => :male } person1 = { :name => "Laura", :age => 23, :gender => :female }
Ruby methods (functions)
- Methods must be defined before they are called.
- The last expression that is evaluated is automatically returned by the method.
def say_hello( name ) "Hello, " + name # Same as: return "Hello, " + name end
- Method calls typically leave out the parens
- Future Ruby versions could require parens, so should retain habit of using parens in method calls.
puts say_hello "Chris" # Same as: puts say_hello( "Chris" )
Ruby Classes and Objects
Discovering classes and methods
- Ruby is sometimes referred to as an “introspective” language. See http://phrogz.net/ProgrammingRuby/ospace.html and https://wikiless.tiekoetter.com/wiki/Type_introspection.
- Finding what class an object belongs to: the
class
method
a = "This is a test" puts a.class
- It is possible to query almost any object in Ruby for the methods that are available to it.
a = "This is a test" puts a.methods.sort.join(' ')
Classes
- The Ruby on Rails web app framework necessitates a working knowledge of classes in Ruby.
class Person attr_accessor :name, :age, :gender # note use of symbols end person_instance = Person.new person_instance.name = "Robert" person_instance.age = 52 person_instance.gender = "male" puts person_instance.name
Intro to class inheritance in Ruby
class Pet attr_accessor :name, :age, :gender, :color end class Cat < Pet end class Dog < Pet # Dog-specific method def bark puts "Woof!" end end class Snake < Pet attr_accessor :length # additional attribute for Snake end
Using instance or object variables (@varname)
# base class Shape class Shape end class Square < Shape # consider initialize method to be the "constructor" def initialize( side_length ) @side_length = side_length end # Instance variables are private by default, so # @side_length is private unless made public with # attr_accessor :side_length # Methods are public unless declared private: def area @side_length * @side_length end def perimeter @side_length * 4 end end class Triangle < Shape def initialize( base_width, height, side1, side2, side3 ) @base_width = base_width @height = height @side1 = side1 @side2 = side2 @side3 = side3 end def area @base_width * @height / 2 end def perimeter @side1 + @side2 + @side3 end end my_square = Square.new( 5 ) my_triangle = Triangle.new( 6, 6, 7.81, 7.81, 7.81 ) puts my_square.area puts my_square.perimeter puts my_triangle.area puts my_triangle.perimeter # Attempt to change @side_length of my_square: my_square.side_length = 10 # will fail without an attr_accessor for :side_length puts my_square.area puts my_square.perimeter
- Note the lack of an
attr_accessor
for these class definitions.- Without
attr_accessor
, instance variables are private by default.
Using class variables (@@varname)
- particularly useful for storing information relevant to all objects of a certain class.
- like static class member variables in C++/Java
- Example: Store the number of objects created so far in a certain class using a class variable.
class Square def initialize if defined?( @@number_of_squares ) @@number_of_squares += 1 else @@number_of_squares = 1 end end # A class method begins with the name of the class itself def Square.count @@number_of_squares # "return" is optional end end a = Square.new puts Square.count b = Square.new puts Square.count
Rubygems: Ruby packaging system
- RubyGems is a packaging system for Ruby programs and libraries.
- Provides gem command
- Can be thought of as Ruby equivalent of CPAN in Perl and 'pip' in Python.
- Try running
# List all available gems; hit q to quit the more pager gem list --remote | more # Download and install gems gem install nokogiri open-uri sqlite3
- Each individually packaged Ruby library (or application) is called a gem or RubyGem.
- https://rubygems.org - The Ruby community’s gem hosting service
Ruby and databases
- Databases and dynamic languages
- Perl and Python also have commonly used modules that allow these languages to use SQL databases.
- The techniques learned in Ruby are probably applicable to Perl and Python programs that manipulate databases.
- Most common use is in web applications that use a database back-end for data storage.
- Why databases w/ Ruby?
- The Ruby on Rails web app framework is optimized for the creation of database-driven web apps.
SQLite with Ruby
- SQLite is a lightweight SQL database that does not require a DB server running in the background.
- Widely-adopted for configuration management, e.g. Firefox, Chrome and related browsers store user profiles, browsing history, etc. in SQLite databases.
- Example: Menu-driven program that allows you to create, manipulate and search a database table.
- See rbdb2.rb
- You need to have the
sqlite3
gem installed. If you successfully installed therails
gem, you have thesqlite3
gem. - After you finish running
rbdb2.rb
, you will have adbfile
in the same directory as the Ruby program.
Ruby on Rails: An introduction
- Ruby on Rails (RoR or Rails) is an open source Web application development framework.
- Goal: Make it possible to develop Web applications in an easy, straightforward manner, with as few lines of code as necessary.
- For this to be possible, Rails makes assumptions and uses default configurations that work for most Web apps.
- The attraction of Rails is that it removes much of the groundwork needed to develop Web apps.
- Features such as database access, dynamic page elements (using JavaScript), templating and data validation are either preconfigured or take only a few lines of code to configure.
Rails & the Model-View-Controller architecture
- Like many contemporary Web app frameworks, Rails uses the Model-View-Controller (MVC) architecture for organizing application programming.
- Splits Rails apps into three sections: models, views and controllers
- Models
- Used to represent forms of data used by the app and contain the logic to manipulate and retrieve that data.
- In Rails, a model is represented as a class.
- Views
- The templates and HTML code that users of the Web app see.
- Turn data into formats that users can view.
- Can output data as HTML for Web browsers, XML, RSS and other formats.
- Controllers
- Form the logic that binds together models, data and views.
- Process input and deliver data for output.
- Call methods that are made available by models and deliver it to the views.
- Contain methods known as actions that generally represent each action relevant to that controller, such as “show,” “hide,” “view,” “delete,” and so forth.
Ruby on Rails: More Information
- Ruby on Rails home: http://www.rubyonrails.org/
- A complete production-level Rails system requires Ruby, the Rails framework (the 'rails' and other Rubygems), a Web server such as Apache or nginx, a database such as MySQL or sqlite, Node.js, and more.
- A Rails development environment requires Ruby, SQLite3, Node.js and Yarn.
Sample app - mydiary
cs498gpl/introduction_to_ruby.txt · Last modified: 2025/04/13 04:55 by jchung