Basics

Ruby: a programming language

Rails: a Ruby framework used for web development
"Ruby on Rails"

Gems: Ruby add-ons (called libraries or packages in other languages) you can include in your project
specify what you need in file "gemfile"

Bundlers: helps you manage Gems and their version dependencies
writes file "gemfile.lock" which specifies exact versions

Ruby files use *.rb extension

Ruby is object-oriented and can also be used for functional programming

can do Desktop and Web apps

Comments

single line comments
hash aka sharp aka pound (#) is used to comment out a line

 # single line comment
 puts 'hi' # more comments

block comments aka multiline comments

=begin
comment line
comment line
=end

=begin
escape character `=being
=end

End Of Line

a statement can be ended with a semicolon (;) or end-line

if a line ends with an operator (+ - \, for example) then the statement will be continued onto the next line

Hello World

file: hello_world.rb

puts 'Hello world'

run in terminal

ruby hello_world.rb

Naming Conventions

Identifiers are names of variables, constants, methods
Identifiers are case sensitive

Class names use camel case: MyClass

Variable names use snake case: my_variable_name, my_variable_name_2
Method names use snake case: my_method_name, my_method_name_2

local variable names start with a lowercase letter or _

Init New Project

in project dir

//in terminal
gem install bundler
touch gemfile

edit "gemfile" to say

source 'https://rubygems.org'

gem 'pry'
(pry is useful for debugging)

run the bundler

//in terminal
bundle install
- installs the gems and their dependencies
- creates gemfile.lock


Basics

HTML stands for Hyper-Text Markup Language. HTML describes the contents of a web page.

CSS stands for Cascading Style Sheet. CSS defines the appearance and layout of a web page.

CSS can be included in the HTML file, or in a separate CSS file.

XML

HTML is a subset of XML. XML stands for Extensible Markup Language. HTML is an extension of this language. It's rules are more specific, but the basic structure is the same.

Template Page

A basic HTML page template

<!DOCTYPE HTML>
<html lang="en">
    <head>
        <meta http-equiv="content-type" content="text/html; charset=utf-8">
        <meta name="description" content="description">
        <meta name="keywords" content="word,word,word">
        <meta name="author" content="author">
        <title>Title Goes Here</title>
    </head>
    <body>
        <p>This is my web page</p>
    </body>
</html>
Whitespace

indentation matters

you can end a line with just an endline character
and you can put multiple statements on one line with ; separating them


x + y #the same as x+y (addition)
x +y #the same as x(+y) where x is a method being invoked

BEGIN

declares code to run first in the program
does not have to be first in the file

BEGIN {
    #code
}

END

declares code to run last when the program is closing

END {
    #code
}
Command Prompt

Verify if Ruby is installed on your system

ruby -v

To run a Ruby file

ruby my_file.rb

Irb

irb means Interactive Ruby
run an interactive Ruby shell in command prompt

irb #open the shell
"quit" or "exit" will close the shell

load a Ruby file into the irb

require './my_file.rb'
you can reload a class after making edits to the file

load './my_file.rb'

tell a program to pause so you can inspect state

binding.irb #like putting a breakpoint in the code
- type "exit" to continue execution

One-Liner

you can run single lines of Ruby from command prompt

ruby -e "puts 'Hello world'"
"-e" means evaluate

Installation: Windows

Installing Ruby on Windows
[Ruby's documentation]

 winget search RubyInstallerTeam.Ruby #this displays the list of available packages
 
 winget install {package-id}
 #example
 winget install RubyInstallerTeam.RubyWithDevKit.3.2
Then restart your command prompt so the updated environment variables are picked up.
You can now run *.rb files directly without saying "ruby" first.

Installation: Mac

install Ruby packages with HomeBrew

//in terminal
brew install rbenv
//maybe this?
rbenv init
//see list of available versions
rbenv install -l
//install
rbenv install 3.2.2
rbenv local 3.2.2
//verify
ruby -v

verify what is installed

//in terminal
which ruby
Unix

making a Ruby file an executable
- make the *.rb file executable (chmod +x my_file.rb)
- include the shebang line in the file

 #!/usr/bin/ruby
 
 puts 'hello world'
now you can run the file without saying "ruby" first

./my_file.rb

"shebang" refers to the "sharp-bang" symbols (#!) that start the line
this tells unix what program to use to run the file

Fonts

Size Units

em = equal to the current font size (if font size is 12px then 1em = 12px), scales linearly
px = pixels are fixed-size units based on the physical computer screen
pt = points come from print media (1 pt = 1/72 inch), fixed size units
% = percent is in relation to the current font size (100% = current font size)
IO

Output

puts
- outputs text
- includes an implicit end line at the end

puts 'text'
puts "text"

print
- outputs text
- does not include an implicit end line

print 'Enter your name: '
print "Enter your name: "

output a variable

puts @my_instance_variable
puts "label: %d" % [@my_instance_variable]

Input

gets
- retrieve user input

print "Enter a word: "
word = gets.chomp


Literals

HTML Entity


<p>A spade character: &spades;</p>
<p>A forced whitespace: &nbsp;</p>
<p>An ampersand: &amp;</p>

Decimal


<p>A spade character: &#9824;</p>

Hexadecimal


<p>A spade character: &#x2660;</p>

Variable

local variables: defined in a method, scope is limited to the method

instance variables: scope is limited to an instance/object, use prefix @ to use the variable

class variables: shared across all instances of a class, use prefix @@ to use the variable

global variables: scope is the entire program, use prefix $ to use the variable

Ruby variables use dynamic typing

my_num = 10
my_name = 'Susan'

Class

Class

"data members" include characteristics and methods


class Person
    #characteristics
    @@lucky_number = 3
    @@name = 'jane'
    #methods
    def say_hello()
        print 'hello'
    end
end

create an instance of a class (create an object)

class Person
end

jane = Person.new
the "new" method is automatically available on all classes

method invocations only require parentheses when there are arguments

class Person
    def initialize(name, lucky_number)
        @name = name
        @lucky_number = lucky_number
    end
    def display()
        puts "name: %s, lucky: %d" % [@name, @lucky_number]
    end
end

jane = Person.new('jane', 3)
jane.display

Initialize Method

initialize is run each time a new instance is created


class Person
    attr_reader :name #not sure yet if this is required for internal reads of the data

    def initialize(name)
        @name = name
    end
    
    def print_name()
        puts @name
    end
end

Instance Variables

instance variables are scoped to one instance of a class


attr_accessor :my_instance_variable

@my_instance_variable = value

puts @my_instance_variable

Accessors

accessors are for reading and writing to an object's instance variables

attr_reader creates public "getter" methods

attr_writer creates public "setter" methods

attr_accessor creates public "getter" and "setter" methods

Root Class

all classes inherit from the class "Class"

Reflection


my_object.class #returns the Class type
my_object.methods #returns a list of Methods


Methods

Definition


//define
def hello_world()
    puts "Hello, world"
end
def greet(name)
    puts "Hello, #{name}"
end

//call
hello_world #no parentheses needed when there are no parameters
greet('Susan')

Return

methods return the output of the last command run in the method
the default is "nil"

explicit return

def sum(a, b)
    return a + b
end

def divide(a, b)
    return if b == 0 #returns nil
    return a / b
end



Instance Method


class MyClass
    def hello_world
        puts "Hello World"
    end
end

my_class = MyClass.new
my_class.hello_world()

Class Method
use the self keyword

class MyClass

    def self.hello_world
        puts "Hello World"
    end
end

MyClass.hello_world
String
Quotes
single quoted strings are literals - '1\n2' does not include an end line double quoted strings interpret escaped characters (backslash notation) - "1\n2" prints 1, then end line, then 2
Interpolation

word = "apple"

sentence = "The #{word} fell out of the tree."
Formatted

x = 5

y = "bob"
message = "x: %d, y: %s" % [x, y]
format specifiers: - %s is for strings - %d is for whole numbers - %04d pads the number to four digits, filling in with leading 0s - %f is for floating point numbers - %0.2f means two decimal places (rounds) - %x converts a decimal to hexadecimal left or right justify strings to a number of characters

a = "apple"

b = a.ljust(10)
c = a.rjust(10)
Common Operations

text.chomp #remove trailing newline and carriage return characters

text.chomp('suffix') #removes trailing "suffix"
text.strip #remove leading and trailing whitespace
text.length
text.upcase #returns uppercase version of string
text.downcase #returns lowercase version of string
text.reverse
text.to_i #parse string to integer
Here Document
build a multiline string specify the custom terminator after "<<"

print <<MYEND

    text text
    text text
MYEND
Conversions
number to string

n = 3

s = n.to_s
Stylesheets
External
Html:

<head>

    <link rel="stylesheet" type="text/css" href="myStyles.css" />
</head>
myStyles.css:

body {

    font-size: 14pt;
}
Internal

<head>

    <style type="text/css">
        body {
            font-size: 14pt;
        }
    </style>
</head>
Inline

<head>

</head>
<body style="font-size: 14pt;">
</body>
Selectors
Selectors can be used in External and Internal stylesheets to specify which elements each style applies to. Select by id

    #id { ... }

Select by class

    .class { ... }

Select by tag

    table { ... }

Select direct children

    table.class > tr { ... }

Select descendents

    table.class td { ... }

A list of selectors

    #id, table.class td, p { ... }

Modifiers

    td:hover { ... } //when mouse hovers over element

    
    button:focus { ... } //when element is in focus
    
    a:link { ...} //unvisited links
    a:visited { ... } //visited links
    a:active { ... } //active link
    a:hover { ... } //if using link or visited with hover, make sure hover is last or the style will be overwritten
Numerics
supports + - * / < > ==
Integers
inherits from the Integer class, so I'm not sure yet if "primitives" is a concept in Ruby

num = 1

doing division with two integers returns the rounded-down result

num.to_f #converts the integer to a float

num.to_s #converts the integer to a string
range operator, includes both the low and the high number

for num in 1..5

    put num #outputs 12345
end
Floats

dec = 1.5

supports .round(places) .ceil .floor
Bools

val = true

val = false
supports && ||
Symbols
a unique and immutable identifier used for naming hash keys or methods similar to strings, but takes up less memory created with a colon prefix

hash = {a: 1, b: 2, c: 3}

Collections
Arrays
an ordered list are stored in contiguous memory (although it may just be an array of memory references to the actual data) can store mixed data types

nums = [1,2,3]

names = ['Susan','Bob']
mixed = [1,'Susan',[45,6.7]]
get element

val = my_array[0]

add elements to array

my_array.push(element)

my_array << element #the shovel operator


remove elements from array

my_array.delete(element)

my_array.delete_at(index)
iterate

my_array.each { |val| puts val } #output each value to the command line


my_array.each do |val|
    puts val
end
Hashes
key/value pairs keys must be unique like a dictionary in other languages

//with symbol keys

my_hash = {name:'Susan', fingers:10}

//with string keys
my_hash = {"name":"Susan", "fingers":10}
get a value

val = my_hash[:symbol_key]

val = my_hash["string_key"]
add a value

my_hash[key] = value

iterate

my_hash.each { |key,val| puts "#{key} -> #{val}" }


my_hash.each do |key,val|
    puts "#{key} -> #{val}"
end
Flow Controls
If

val = true

puts "text" if val #will skip this statement if "val" is false

if age > 35

    puts "over 35"
elsif age > 25
    puts "over 25"
else
    puts "up to 25"
end
Unless

val = true

puts "text" unless val #will skip this statement if "val" is true
While

while counter < 10

    count += 1
end
For

for num in 1..5

    puts num #outputs 12345
end
Operators
Nil Safe
"&." in Ruby is like "?." in C# if will save you from nil exceptions when using fluent syntax for multiple piped operations

result = text&.upcase&.reverse

Errors/Exceptions
Error Types
syntax errors no method errors runtime errors
Error Handling
"begin", "rescue", "end" are working together

begin

    puts 10/0
rescue StandardError => e
    puts "an error occurred: #{e.message}"
end
Pry
from the standard Gem "pry", for complex scenarios a more powerful tool than binding.irb add this line into your code where you want to debug

require'pry';binding.pry

the terminal will open a pry prompt you can work in type "exit" to exit this pry, and execution will continue to the next one