Notes and Quotes Flashcards
The value returned by a Ruby method is the value of the last expression evaluated, so we can get rid of the temporary variable and the return statement altogether
Example 1:
def say_goodnight(name) result = "Good night, #{name.capitalize}" return result end puts say_goodnight('uncle') produces: Good night, Uncle
Example 2:
def say_goodnight(name) "Good night, #{name.capitalize}" end puts say_goodnight('ma') produces: Good night, Ma
nil
In many languages, the concept of nil (or null) means “no object.” In Ruby, that’s not the case; nil is an object, just like any other, that happens to represent nothing.
Optimal way to create an array of words
a = %w{ ant bee cat dog elk }
Where do objects come from?
Every object in Ruby was generated either directly or indirectly from a class
Understanding Attributes
That state is private (instance variables used to create initialize objects) to those objects—no other object can access an object’s instance variables. In general, this is a Good Thing. It means that the object is solely responsible for maintaining its own consistency.
However, an object that is totally secretive is pretty useless—you can create it, but then you can’t do anything with it. You’ll normally define methods that let you access and manipulate the state of an object, allowing the outside world to interact with the object. These externally visible facets of an object are called its attributes.
Accessor Method (reader - long way)
We used accessor methods to access the attributes of our objects (remember, the instance variables can’t be accessed by other objects).
def isbn
@isbn
end
This accessor method returns the value of the instance variable because it’s the last thing evaluated.
This type of accessor method allows you to READ the attribute, but not write to it.
Accessor Reader Method (short way)
attr_reader: :isbn, :price
This is the same as writing:
def isbn
@isbn
end
def price
@price
end
Accessor Method (writer - long way)
Sometime, your instance variables need have the ability to be set from outside of the object. In this case, it needs to be able to be written to.
You do that by creating a method who name ends in an equal sign.
Example:
def price=(new_price) @price = new_price end
So you can follow the structure, this is till just a method that takes a variable. Similar to these constructs.
variable(new_price)
variable!(new_price)
variable?(new_price)
This method just happens to end with an equal sign.
variable=(new_price)
Inside the method, it sets the attribute to the input. Simple Reassignment.
book = BookInStock.new(“isbn1”, 33.80) puts “ISBN = #{book.isbn}”
puts “Price = #{book.price}” book.price = book.price * 0.75
puts “New price = #{book.price}”
produces:
ISBN = isbn1 Price = 33.8 New price = 25.35
Accessor Method (writer - short way)
attr_writer :isbn,
This is the same as:
def isbn=(updated_isbn) @isbn = updated_isbn end
Atrribute Accessor (both read and write)
attr_accessor :isbn, :price
Failing to make attributes accessible, reading or writing:
If you fail to make your instance variable readable, you will get an error similar to this:
Test.rb:12:in ': undefined method
name’ for # (NoMethodError)
What is a virtual attribute?
A virtual attribute is a derivative of the original attribute. It will be defined as a getter and setter and will change the original attribute.
Example:
class BookInStock attr_reader :isbn attr_accessor :price def initialize(isbn, price) @isbn = isbn @price = Float(price) end def price_in_cents Integer(price*100 + 0.5) end def price_in_cents=(cents) @price = cents / 100.0 end # ... end
book = BookInStock.new(“isbn1”, 33.80)
puts “Price = #{book.price}”
puts “Price in cents = #{book.price_in_cents}” book.price_in_cents = 1234
puts “Price = #{book.price}”
puts “Price in cents = #{book.price_in_cents}”
produces:
Price = 33.8 Price in cents = 3380 Price = 12.34 Price in cents = 1234
Uniform Access Principle (unfinished)
This is more than a curiosity. In his landmark book Object-Oriented Software Construc- tion [Mey97], Bertrand Meyer calls this the Uniform Access Principle. By hiding the dif- ference between instance variables and calculated values, you are shielding the rest of the world from the implementation of your class. You’re free to change how things work in the future without impacting the millions of lines of code that use your class. This is a big win.
require_relative
Require relative is used to load in a file where the location is in the same directory.
This is an example of requiring and external library and internal file:
Example:
require ‘csv’
require_relative ‘book_in_stock’
When will you get an error for access control (restricted methods)?
Access control is deter- mined dynamically, as the program runs, not statically. You will get an access violation only when the code attempts to execute the restricted method.
How do you set access control for entire groups of methods?
class MyClass def method1 #... end protected def method2 #... end private def method3 #... end public def method4 #... end # default is 'public' # subsequent methods will be 'protected' # will be 'protected' # subsequent methods will be 'private' # will be 'private' # subsequent methods will be 'public' # so this will be 'public' end
How do you set access control for individual methods
class MyClass def method1 end # ... and so on public :method1, :method4 protected :method2 private :method3 end
Read over this example of when to use access control - a bank.
In this case, we are dealing with accounting for a bank. The transaction dictates what happens to debit or credit section. The debit or credit section can’t be set themselves.
class Account attr_accessor :balance def initialize(balance) @balance = balance end end class Transaction def initialize(account_a, account_b) @account_a = account_a @account_b = account_b end private def debit(account, amount) account.balance -= amount end def credit(account, amount) account.balance += amount end public #... def transfer(amount) debit(@account_a, amount) credit(@account_b, amount) end #... end savings = Account.new(100) checking = Account.new(200) trans = Transaction.new(checking, savings) trans.transfer(50)
Example of Protected
class Account
attr_reader :cleared_balance # accessor method ‘cleared_balance’ protected :cleared_balance # and make it protected
def greater_balance_than(other)
return @cleared_balance > other.cleared_balance end
end
Because cleared_balance is protected, it’s available only within Account objects.
Arrays and hashes. Mastery of these two classes is key to being an effective Ruby programmer.
Arrays and hashes. Mastery of these two classes is key to being an effective Ruby programmer.
Where does a class get it’s characteristics?
If you don’t define an explicit superclass when defining a class, Ruby automatically makes the built-in class Object that class’s parent.
class Parent end
puts “The superclass of Parent is #{Parent.superclass}”
produces:
The superclass of Parent is Object
Further:
puts “The superclass of Object is #{Object.superclass}”
produces:
The superclass of Object is BasicObject
Even further:
puts “The superclass of BasicObject is #{BasicObject.superclass.inspect}”
produces:
The superclass of BasicObject is nil
What are the two main benefits of modules?
Modules provide a namespace and prevent name clashes.
Modules support the mixin (a mixin is like a partial class definition) facility. This provides a controlled multiple-inheritance-like capability with none of the drawbacks.
How do you bring in a module?
Load in the modules in the new file.
Example:
File 1:
module Trig PI = 3.141592654 def Trig.sin(x) # .. end def Trig.cos(x) # .. end
File 2:
module Moral VERY_BAD = 0 BAD =1 def Moral.sin(badness) # ... end end
File 3:
require ‘trig’
require ‘moral’
Mixin Hierarchy
If a class has multiple modules mixed in, the last one included is searched first.
are blocks objects?
No.
Because of this, blocks can’t be saved to variables and don’t have all the powers and abilities of a real object.
ending a line in ruby
if you want to end a Ruby statement without going to a new line, you can just type a semicolon. This means you can write something like:
class Monkey; end