-
-
Save laurenlucero/4d77b7249d1df3a2020218189ccc7604 to your computer and use it in GitHub Desktop.
"strings"
are objects so they have a lot of .methods
Strings represent text and data.
:symbols
are identifiers to represent method & instance variable names.
Every symbol is unique.
Symbols are immutable (can't be changed).
Symbols are not pointers to values, they are values themselves.
You should use symbols as names or labels for things (like methods) & use strings when you care more about the data (individual characters).
You might convert a symbol to a string because symbols only have a subset of the methods that a string has and symbols can’t be changed.
If you want to work with the individual characters of the symbol then use.to_s
You can also convert a string object into a symbol using .to_sym
To create an array of symbols:
symbols = %i(a b c)
[:a, :b, :c]
To creat an array of strings:
strings = %w(a b c)
["a", "b", "c"]
A Hash is a dictionary-like collection of unique keys and their values AKA associative arrays. They are similar to Arrays, but where an Array uses integers as its index, a Hash allows you to use any object type.
nil
is a special Ruby object used to represent an “empty” or “default” value.
It’s also a “falsy” value, meaning that it behaves like false
when used in a conditional statement.
Everything else in Ruby is considered true
in a boolean context.
In Ruby we don’t have a Boolean class, but we have boolean objects!
true
& false
are the singleton objects of TrueClass
& FalseClass
Boolean logic: AND & true/true=true true/false=false OR | true/true=true true/false=true XOR ^ true/true=false true/false=true
File methods:
Read & Write files in Ruby with File.read
& File.write
Renaming a file
File.rename("old-name.txt", "new-name.txt")
File size in bytes
File.size("users.txt")
Does this file already exist?
File.exists?("log.txt")
Get the file extension, this works even if the file doesn't exists
File.extname("users.txt")
=> ".txt"
Get the file name without the directory part
File.basename("/tmp/ebook.pdf")
=> "ebook.pdf"
Get the path for this file, without the file name
File.dirname("/tmp/ebook.pdf")
=> "/tmp"
Is this actually a file or a directory?
File.directory?("cats")
Regular expressions help you find specific patterns inside strings, with the intent of extracting data for further processing. Two common use cases for ruby regex include validation & parsing. Using a tool like Rubular can help you build your ruby regex in a more interactive way.
A gem is a package aka dependency that adds extra functionality to your Ruby program. A Bundler is a tool for dependency management.
Classes are the basic building blocks in OOP & they help you define a blueprint for creating objects ::class_method
Objects are the unique products of the class, an individual “thing” with its own identity & its own data.
Class names start with an uppercase letter.
We use the class
keyword then the end
keyword.
Variables
An @instance_variable
is something your class knows and defines attributes.
@@ClassVariables
attribute all related objects
$GlobalVariables
can be used anywhere
Enumerable is a Ruby module used to iterate over the elements of any class that implements the each
method, like Array, Range & Hash
Blocks allow methods to take arbitrary snippets of code as arguments and run them Can be implicit or explicit
Procs is the concept of passing functions as arguments to other functions aka higher order functions
We can pass a proc
object instead of a block to any method by prefixing it with &
In Ruby, you might express “multiply each element of this collection by 2 and return the result” by passing the anonymous function n * 2 to the Enumerable#map method:
[1, 2, 3].map { |n| n * 2 } # => [2, 4, 6]
Proc example:
double = Proc.new { |n| n * 2 }
[1, 2, 3].map(&double) # => [2, 4, 6]
Ruby doesn’t immediately try to run the Proc
passed into the function but instead calls #to_proc
on it before execution which allows us to pass in any object that responds to #to_proc
Symbol
defines #to_proc
as a function that sends the message of the same name as the symbol to the target object i.e.
[1,2,3].map(&:to_s) # => ["1", "2", "3"]
sends the message :to_s
to each item in the array
inject
aka reduce
is one of the most powerful methods provided by Enumerable
Constants are a type of variable defined by starting with a Capital Letter or ALL CAPS which should not change.
You can change the value of a constant but it will print a warning.
Class names are constants.
Avoid const_get
with user input.
An environment variable is a key/value pair to share configuration options between all the programs in your computer
require
and load
are file-level methods used to "read" and parse files
include
and extend
are language-level methods that can extend your class with other modules
RubyGem
Each gem has a name, version, and platform.
For example, the rake gem has a 0.8.7 version (May 2009). Rake’s platform is ruby
, which means it works on any platform Ruby runs on.
Inside gems are the following components:
- Code (including tests and supporting utilities)
- Documentation
- gemspec
Common RubyGems Commands:
gem search ^rails
find
gem search ^rails$ -d
find with details
gem install ><
gem uninstall ><
gem list
ri ><
view docs
gem fetch ><
audit contents without installing then
gem unpack ><
to extract content or use this modify installed gem
gem help platform
Exceptions are Ruby's way of dealing with unexpected events.
"rescuing," "handling," or "catching" an exception means stopping the shutdown process caused by an error
begin
# Any exceptions in here...
1/0
rescue
# ...will cause this code to run
puts "Got an exception, but I'm responding intelligently!"
do_something_intelligent()
end
^ This program does not crash.
Exception objects are normal Ruby objects that hold all of the data about "what happened" for the exception you just rescued.
"raising" with the raise
method triggers your own exceptions
To make a custom exception, just create a new class that inherits from StandardError
class PermissionDeniedError < StandardError
end
raise PermissionDeniedError.new()
-
Rescuing errors of a specific class also rescues errors of its child classes.
-
Never rescue Exception in Ruby! The problem with rescuing Exception is that it actually rescues every exception that inherits from Exception. Which is....all of them!
-
Rescue StandardError Instead! All of the exceptions that you should care about inherit from StandardError. These are our old friends:
- NoMethodError - raised when you try to invoke a method that doesn't exist
- TypeError - caused by things like 1 + ""
- RuntimeError - who could forget good old RuntimeError?
class SomethingBad < StandardError
end
raise SomethingBad
The Exception Tree:
Exception NoMemoryError ScriptError LoadError NotImplementedError SyntaxError SignalException Interrupt StandardError ArgumentError IOError EOFError IndexError LocalJumpError NameError NoMethodError RangeError FloatDomainError RegexpError RuntimeError SecurityError SystemCallError SystemStackError ThreadError TypeError ZeroDivisionError SystemExit fatal
==
returns true if both objects can be considered the same
===
checks equality in case
statements
eql?
checks if 2 objects refer to the same hash
key
when you actually need to check if two objects are the same object there’s the method equal?
ex: "A".equal?("A")
returns false
Other comparison operators are: less than <
, less than or equal <=
, greater than >
, and greater than or equal >=
the ==
, ===
and eql?
methods are designed to be overridden in specialisations of the Object
class
the only method to check object equality at an object ID level is equal?
Composition-based solutions break up a problem into distinct responsibilities and encapsulate the implementation of each into separate objects. Composition is a more robust and flexible approach to architect reusable object-oriented software.
In an inheritance-based solution, a given object often has multiple responsibilities it has inherited from its various ancestors. Only reach for inheritance when it makes sense such as when building ActiveRecord
models.
Delegation and method forwarding are useful patterns for dividing responsibilities between related objects. In plain Ruby projects, both Delegator
and Forwardable
can be used, whereas Rails code tends to gravitate towards its delegate
method. For maximum control on what is delegated, the Casting
gem is an excellent choice, though it's slightly more complex than the other solutions.
In Ruby the Observable module makes it possible for an object to maintain a list of its dependents and notify them automatically of any state changes.
Use the Singleton module in Ruby to create singleton classes and prevent other instances from accidentally being created.
The Singleton pattern is simply an object-oriented programming pattern where you make sure to only have 1 and only 1 instance of some class. Ruby implement the Singleton pattern with a module: just write Include Singleton in your class definition and you're good to go.
- Classes are what we use to define our objects (classes are just a particular kind of object)
- Instances of classes are the objects created by our classes
- The Eigenclass is called the Singleton class because it is a Class that follows the Singleton pattern.
The metaclass is called the singleton class because there is a single instance of it. Just like instance methods are defined in a class, class methods are defined in the metaclass of a class object. The inheritance chain of metaclasses is what allows to inherit and override class methods and call super.
Type introspection is a core feature of Ruby that makes it possible for your code to ask questions about itself. With type introspection a program can examine the type or properties of an object at runtime.
ObjectSpace
gives you information about the current state of your application. Using ObjectSpace
you can know what objects are currently ‘alive’ in your program.