Tricks and One Liners

When defining a method to take blocks, use an ampersand in the parameters where the block will be given. This converts the block to a proc object and assigns it to the name of the parameter. Why write a method to take a block? It allows you to customize a method by injecting some logic into it. The body of the method is where the basic structure is built, where you put loops or iteration or self refference (recursion).

I think when writing a method that will take a block, you have to assume to know how many arguments the block will take.

You can design the method to take a short burst of logic (given when the method is called) and apply it where needed.One way this is useful is in writing class methods that generate instance methods with custom logic:

Writing Methods

Methods

Inspect - a method in the Object class which means it is available to all other classes unless specifically overwritten. It presents a reperesentation of the object in a readable string. For built-in objects, this will just be the object itself in a string. When an instance of a class is called, inspect is the method being used by default to display the instance. Inspect can be modified for user defined classes:

Called on an array. Takes one or more arguments, converts them to arrays and combines them with .self and returns an array of arrays of combined elements. Generates an array of length n, where n is 1 more than the number of arguments. If the arguments are shorter than .self, nil values will be provided.

Merges target_hash into hash1. Duplicate keys are superseded by the target hash. The order of keys will be hash1...target_hash

Array#each - The .each method accepts a block of code to which each element of the array is passed in turn:

defarray_copy(source)destination=[]#create a new empty arraysource.eachdo|n|#submit each element in the array to the following blockdestination<<nifn<4#push n to array ‘destination’ if n is less than 4endreturndestinationend

inject is a method inside of enumerable that allows you to get the sum or product of the contents of an array if all the elements are numeric values. inject is given a method argument then a block containing two parameters representing the so-far accumulated value and the next element to be operated on. ‘inject’ will run on each element in the array and then return the final accumulated value.

nums=Array(1..10)nums.inject(0)do|accum,ele|#accum set to given argument 0 but can be any value.accum+elementendstdout:
=>55nums.inject(:+)#A cool shortcut that does the same as the above code.nums.inject(:*)#Also works for returning a product.nums.inject('')#Will set the accum value to an empty string.

Combines all elements of an enumerable using a binary operator or named in a method or block passed to #inject. Inject has an accumulator value called memo (short for memory?) that takes the accumulator value and each element. Memo is held by a block or associated with a symbol passed to inject ( :*, :+, :/)

Inject the memo in inject will be whatever value is present at the end of each iteration of the given block. It can be an array if that’s what is being generated inside the block. Whatever is being done to x…

select takes elements of an array or a range and tests them against a code block. All the elements that return true are returned in a new array.

nums=(1..30)arr=nums.selectdo|i|i%2==0endarr=>[2,4,6,8,10]

include? - Takes an object as a parameter and returns a Boolean value if any item in the array is equal to that object.

nums=(1..10)nums_arr=Array(1..10)nums_hsh={1=>"a",2=>"b",3=>"c",4=>"d",5=>"e"}putsnums.include?(5)=>trueputsnums.include?(11)=>falseputsnums_arr.include?(5)=>trueputsnums_arr.include?(11)=>falseputsnums_hsh.include?(3)=>trueputsnums_hsh.include?(11)=>falseputsnums_hsh.include?('c')=>false#.include? can't access values in a hash. Use .has_value?

any?all? and none? return a Boolean based on the given code block for the members in their collection. Check to see if an array has any element greater than zero, any odd/even elements, if all elements are positive etc.

nums=[2,3,5,7]nums.any?do|i|#will return true of any elements are even.i%2==0end=>true

map returns a new array with the results of running the called block on each element:

arr<<"thing"#adds element to the end of an arrayarr.push("thing")arr.unshift("thing")#adds element to the beginning of an array (index 0)arr.insert(3,"thing")#adds element to the specified index (in this case index 3)

Remove from an array:

arr.pop=>lastelementinarray#removes and returns the last elementarr.shift=>firstelementinarray#removes and returns first element - (index 0)arr.delete_at(2)# delete element at a particular index in this case 2#special removal:arr.compact#removes all nil values from the arrayarr.uniq#removes all duplicate values in the array

Again, the code in the braces assigns a temporary variable ‘word’ to the elements in the array. It then measures the length of that element against an integer returning a Boolean value. A word will only be selected if the block evaluates to true.

An array within an array is sometimes called a 2 dimensional array or a matrix. An array of arrays will print all the elements in each array. To access individual elements inside an array use arr[outter_arr][inner_arr]

rect1=[[[1,1],[8,4]],[[5,6],[3,1]]]prect1[0][1][0]=>8

you can flatten these nested arrays by using the method #flatten. To use a method like ‘map’ or ‘each’ on a matrix you have to nest the method the same number of levels that are in the array.

.max and .min are enumerable methods and will find the greatest and least
values in an array. Same as .sort.pop and .sort.shift

Hash - Hash tables exist in curly braces (like a block of code? Are they a block?) Hash tables are like an array? In an array, the index is invisible but always the same (it is inherent or implied?). They always have the same default index system: 0, 1, 2, 3.. A hash table’s index can be defined along with the values it contains. If a restaurant menu was represented as a hash table then the index could be made up of the item names and the values they point to could be the price. Index location (called a key) “chicken_sandwich” could point to the value $5.65. In an array you can find a value associated with an index location. In a hash table you find a value associated with it’s key.

Some things to remember about Hash tables:

all keys in the same level of a Hash table must be unique:

pets={:pet=>{:name=>'Steve',:species=>'cat',:age=>8},:pet=>{:name=>'bill',:species=>'dog',:age=>2}}# warning: key :pet is duplicated and overwritten on line 1pets=>{:pet=>{:name=>"bill",:species=>"dog",:age=>2}}more_pets={:cat=>{type: :pet,:name=>'bob',:age=>3},:dog=>{type: :pet,:name=>'frank',:age=>9}}more_pets=>{:cat=>{:type=>:pet,:name=>"bob",:age=>3},:dog=>{:type=>:pet,:name=>"Ann",:age=>9}}

To create an empty hash:

hsh={}=>{}hsh=Hash.new=>{}

Pass a block when creating an empty hash so newly created keys can have default values.

hsh={"noodles"=>8,"tea"=>3}=>{"noodles"=>8,"tea"=>3}hsh=Hash["a",1,"b",2]=>{"a"=>1,"b"=>2}defartaxa=[:punch,0]#two elements to be turned into a key value pairb=[:kick,72]c=[:stops_bullets_with_hands,false]key_value_pairs=[a,b,c]test=Hash[key_value_pairs]endartax=>{:punch=>0,:kick=>72,:stops_bullets_with_hands=>false}hash_test={}hash_test[key1]=1hash_test[key2]=2phash_test=>{key1=>1,key2=>2}

Add/remove and access key value pairs in a hash:

#add to a hash:hsh={"a"=>1}hsh["b"]=2hsh=>{"a"=>1,"b"=>2}

Hash default values:

normal={}#creates an empty hash. no keys or values.not_there=normal[:wig]#not_there is assigned to the value paired with the key ':wig' inside 'normal'normal=>{}puts"Wasn't there:"=>"Wasn't there:"not_there=>nil#‘not_there’ points to the hash value of ‘normal’ at its key ‘:wig’ which is nil#nil is the default value for nonexistent valuesusually_brown=Hash.new("brown")#the empty hash is given a default valuepretending=usually_brown[:zig]puts(usually_brown)=>{}pretending=>"brown"#the nonexistent hash key contained in ‘pretending’ is evaluated and returns ‘brown’

Make a populated hash using #map method. Creates a Hash called cats with keys from 1 - 100 (generated from a range) pointing to a value (in this case the string “no hat”)

General

Gem - A Ruby Gem is a packaged Ruby library. Packaging makes it easy to manage, download, install, update, remove, etc. Gems are handled by RubyGems, a package manager of sorts for gems.

Bundler - Bundler allows you to make your app more portable by automatically installing required gems listed in your Gemfile. Bundler is itself a gem and uses RubyGems to find, download and install required gems. Bundler is helpful because if you move your application to a new location you can ensure that all required gems will be installed when bundle install is run.

tIDENTIFIER - or tINTEGER, tSTRING. These are words in standard Ruby syntax error messages meant to help you debug your code. They hint at the type of object that the interpreter encountered and caused an error They usually appear in a form similar to:

heredoc - Generally, a Here Document, or heredoc, is an input stream in a programs source code that is treated like a separate file. It is a delimited chunk of text that the program can read in like a string and interpret as code. The benefit of using a heredoc is that the ‘body’ of the heredoc can be formatted in a way that is native for its content.

In Ruby, begin the input of a heredoc with a<<, <<- or <<~.

With << the delimiters must start on the first column or they will be included in the heredoc.

Use <<- to begin and end with delimiters starting on any column.

<<~ omits common indentation in the heredoc.

Follow the beginning symbol with a delimiter keyword, then write the body of the heredoc appropriately formatted and end it with the same delimiter keyword.

Sigils in Ruby - Sigils are the non-alphanumeric characters that decorate variables in Ruby. They always go before a variable.

no sigil on a variable means it is a plain local variable.

@ makes a variable an instance variable
These variables are variables that belong to a particular object instance.

$ sigil makes a variable global - valid everywhere in the script.
But these are not Constants. Call the method global_variables to see all assigned global variables.

@@ are for class variables. These are shared among objects of a class. If one object instance changes the value of the variable, that new value will essentially change for all other object instances.

Double Underscores the double underscores that surround certain variables indicate that the variables are special and should not be overwritten. __FILE__ is a special variable that reffers to the actual file that is being interpreted. Calling __FILE__ will prnt the name of the fil.

begin/rescue/end blocks in Ruby - In Ruby, the rescue clause is used along with begin and end to define blocks of code that handle exceptions. For example:

begin and end define a section of code to be run wherein if an exception occurs, it’s handled by the code inside the rescue block. If the following code had been run:

>puts10/0test.rb:1:in`/': divided by 0 (ZeroDivisionError)

Which is an error that will crash a program. The rescue block prevents a crash by running its code (in this case, just printing a message) instead of exiting the application.

This gets to why using different exception classes is important and why the ability to create custom exception classes is super functional. With rescue, different exceptions can be handled differently. For example, the above code causes ZeroDivisionError which you might want to trigger a certain message as opposed to a NameError which will trigger something else.

>begin>#code...>rescueZeroDivisionError>puts"You caused an error!">rescueNameError>puts"you caused a different error and here's why...">end

The above code will output different messages depending on what exception is rescued.

Naked Rescue - I believe this means rescuing without referencing a specific type of exception?

Thoughts on Methods - A method is a basic Ruby command. Methods are called or invoked on to objects. When we call a method, we always use the format object.method (like noun.verb). puts is one of the most basic Ruby commands. puts tells ruby to print out a string, numbers, or an array.

gets, to_i, and to_s are also methods. chomp is a method that removes the newline character from the end of a string. Methods can be combined by placing a . between them.

gets.chomp calls the gets method to get user input and then calls the chomp method on that input. gets.chomp.to_s and gets.to_s.chomp give the same result. I don’t know if the order of methods is always arbitrary. Some methods, like puts need an argument. chomp and gets do not need arguments. gets().chomp().to_s() is read the same as gets.chomp.to_s.

More on the chomp method. name = gets.chomp produces a new string without the newline; it does not modify or change the original string. After using name = gets’ usingname.chomp’ and then calling on name does not have the same effect. name.chomp creates a new string that is not called on when we simply call the variable name. puts("Hello " + name.chomp + "!") creates a new string and uses it immediately giving the same effect as using ‘name = gets.chomp’ but the original variable ‘name’ still contains the string with the newline character. In IRB. When I create a new method in the main:Object (top level, “irb(main):01” right after opening a new irb session), it has the following properties:

defis_a_stringstring_in_this_method="Im a string in the \"is a string\" method."putsstring_in_this_methodstring_in_this_methodend

If I call methods it is not in the returned list

If I call private_methods it is in the returned list

If I call class on the new method

is_a_string.class

String is returned. This is because the last expression in the method definition is the variable pointing at a string, so the method always returns a string.

The new method is not in String.methods or in hh".methods (an instance of string).

The new method is in String.private_methods and hh".private_methods

The new method is not in String.instance_methods

The new method is in BasicObject.private_methods

So where and when can this method be called? I can call it in main:Object

irb(main):087:0>is_a_stringImastringinthe"is_a_string"method.=>"Im a string in the \"is_a_string\" method."irb(main):088:0>

.class on the above expression returns Fixnum. Of course methods in the String class can return a Fixnum. Just like calling .length on a string.
Just like running .to_s on an integer returns a string, even though “to_s” is a method in the Fixnum class ( and an instance method).

Methods have to be called on an object. When I define a method in main:object, at the top level of IRB, and call it, it’s being called on the main:Object

Methods have a “receiver” , which is the data object to the left of the method being invoked.
* In the expression x.y (object.method) x is the receiver of y.
* For private methods the receiver is always “self”

Private Methods - Private methods are always called on self in the context of the current object. If i enter string".private_methods I can see an array of private methods associated with string objects. These cannot be called on the string object itself ( string.global_variables for example ) but must be invoked on self within the context of the string object. I think when public or other methods are called on a string object, behind the scenes, Ruby jumps into the context of the string object and invokes its private methods to return the requested data which may be a string, fixnum, or an array. (Integer and Array are both private methods of string objects, btw)

This is why you can use main:Object private methods initially in Ruby. You start off in the context of the main object and can use private methods (like puts and rand) to return data.

Adding self in front of method names when defining - When adding a method to a class what you are usually making are instance methods that can be called on instances of that class. Class methods can be called on the class itself. For example .new can be called on a class itself to instantiate an object of that class. When defining methods inside a class, add self (for example self.celsius_to_fahrenheit) to the front of the method name to make it a class method. Now you can call Temperature.celsius_to_fahrenheit (on the class itself as opposed to a temperature object).

Passing a symbol or a method to a method instead of a block. - Some methods, like #each, #each_cons and #map, can take blocks of code as a parameter. As a shortcut, these can also take a unary (only operates on one value(operand). Doesn’t combine or return something from 2 values. Like #succ only increases the value of one number by one. It doesn’t need more operands.) method or operator as a symbol to achieve the same effect. Must be a method or instance method of the object?

Operands - These are the objects operated on by operators. In a + b = ca, b, and c are operands.

Modulus - The % operator, called the modulous gives the remainder of two numbers. In Ruby, the following work:

8%2=>02%8=>28%-2=>0-2%8=>6

Variables allow you to store data in an object (strings, numbers, arrays). Variables are assigned. A variable name consists of letters and numbers. It must start with a lowercase letter. It cannot contain spaces. Variables ARE NOT THEMSELVES OBJECTS (They CAN be objects, though?). Variables are names that point to values? The value is the Object.

Instance Variables - These are variables that are accessable to one instance of a class. In the clase of several instances of a class existing simultaneously, each instance will only be able to access it’s own variables.

Argument - An argument is the data that is passed into a method. In puts("yo!")puts is the method and "yo!" is the argument. If a method requires an argument it must have parentheses ( ‘puts()’ for example). Some methods don’t require an argument and therefore don’t need parentheses (‘gets’ for example can be written by itself.

if statements. The if test is really saying “if true, go to body and run code. If false go to end.

code branching is what allows your program to do different things depending on different conditions. By using if, else, and elsif, for example.

puts("Type in a number")#In one line, we use `gets` to read a string from the user, then#immediately call `to_i` on the string to return an integer.num=gets.to_iifnum<10puts("That's not a big number!")endputs("Thanks for typing in a number!")

The if has two parts: the conditionalnum < 10 and the body puts ("That's not a big number!"). The test should be a Ruby expression that returns true or false. The body can be multiple lines long. The special keyword end indicates the end of the body. If the test is true, Ruby will run the code in the body. If the test is false, Ruby will skip it. In this example, if the user types a number less than ten, the program will tell them it is not a big number. Regardless whether the number is big or small, the program will thank them.

puts("Type in a number")num=gets.to_iifnum<10puts("That's not a big number!")elseputs("Wow, that's a big number!")endputs("Thanks for typing in a number!")

By using the else keyword, we create a second body that will run only if the above if test is false. if false then go to else then to end. if true then go straight to end. When if is true it always goes to the end of it’s body, skipping all the else or elsif statements.of it’s body, skipping all the else or elsif statements.of it’s body, skipping all the else or elsif statements.

&& and || are both logical connectives. In if (x) && (y) the if test will return true only when both x and y are true. We then move straight to the end of the body. In if (x) || (y) the if test returns true when either x or y are true.

About expressions in parentheses. Expressions in parentheses are one (object or argument?). ‘number == (7 || 13)’ does not read "Number is equal to 7 or 13”. Instead, Ruby will compare ‘number’ to everything in the parentheses at once (similar to the order of operations, or PEMDAS?). In Ruby the || method works left to right, returning when it finds something that reads as true. In ‘(7 || 13) Ruby asks, is the right operand (7) true? Any number besides ‘nil’ or ‘false’ is inherently true, so Ruby returns 7. So, if ‘number’ equals 13 the statement ‘number == (7 || 13)’ will return false because ruby thinks it is being asked if number == 7. The correct if statement is ‘if (number == 7) || (number == 13)’. ‘if (number == 7 || number == 13)’ also seems to work.

Data structures: integers (numbers) and strings are data structures (types?). Not sure where floats, and other types fall into this.

An array is another data structure. Arrays store a sequence of objects separated by commas ‘[1, 2,…]’. The index of the array is the position of the items in the array. ‘puts(cool_things[0])’ prints item at index 0, which is the first item in the array. Array indices always start at zero. An array with 4 items will have an item at index 0, 1, 2, and 3. We can use the length method to return the number of items in a array as an integer ‘array.length’.

To create a new method we use the method ‘def’ followed by the body and ending with ‘end’. Anything in the body (loops, statements, etc…) will not be run until the method is actually called.

To return a value from a method we use the return keyword before the end of the defined method. return goes in the method body. It can go anywhere in the body and will always break us out of the method, whether it’s returning a value or not. In the following:

The caller will give the input number_of_squares; this method will return an array consisting of the squares for numbers from 0 up until the number specified by ‘numberofsquares’.

deffirst_square_numbers(number_of_squares)squares=[]idx=0whileidx<number_of_squaressquares.push(idx*idx)idx=idx+1endreturnsquaresendputs("How many square numbers do you want?")number_of_desired_squares=gets.to_isquares=first_square_numbers(number_of_desired_squares)idx=0whileidx<squares.lengthputs(squares[idx])idx=idx+1end# Output:# How many square numbers do you want?# 7# 0# 1# 4# 9# 16# 25# 36

The array squares is returned by the method first_square_numbers. The variable squares is assigned in the actual program after the method is defined. It is populated with whatever the return of the method first_square_numbers is. Inside the method, another variable called squares is assigned. This contains the value that is eventually returned but it is actually a whole new variable and could be named anything (a local variable I think?).

Breaking out of loops the break command (keyword?) is used to break out of normally infinite loops.

return - Returns a value and exits a method. More accurately, return is a keyword that takes an argument (nil by default) and exits the method early with that value.

defhi(a)b=a*3return"whatever"bendhi(3)=>"whatever"

A method will always return the value of the most recent evaluated statement inside that method but return can be used to exit a method early if a conditional statement is satisfied, for example. You can also return multiple values from a method

deffoo(a,b)returna,bendfoo3,5=>[3,5]

Interpolation - Interpret variables and blocks of code inside a string. The string must be enclosed in double quotation marks for interpolation to work

a=1b=4puts"The number #{a} is less than #{b}"=>"The number 1 is less than 4"defstring_length_interpolater(argument_string)"The string you just gave me has a length of #{argument_string.length}"endstring_length_interpolater("Hello there!")=>"The string you just gave me has a length of 12"

Placeholders are not just variables. Any valid block of Ruby code you place inside #{ } will be evaluated and inserted at that location. A String literal created with single quotes does not support interpolation!

Concatenating Strings. Adding two strings together is called concatenation. To create a new string by adding two together:

'Ruby'+'Monk'stdout:
RubyMonk

The literal and expressive method for String concatenation is String#concat:'Ruby'.concat(‘Monk’) = ‘RubyMonk'

You can use << just like + but in this case the String object ‘Monk’ will be appended to the object represented by ‘Ruby’ itself. In other words, when you run ‘Ruby’ + ‘Monk’ you’re left with a new string ‘RubyMonk’ in addition to the two sub strings. Using << leaves you with just one string. It’s like using Array#push to add new elements to an array.

Regular Expression or RegEx. Used to match particular characters, words, or patterns of characters. In Ruby you specify a RegEx by putting it between a pair of forward slashes /. RegExs seem a little crazy. Apparently all of these work:

'RubyMonk'.gsub(/[aeiou]/,'1')

replaces all the vowels in the string with the character 1. The RegEx interprets #‘/[aeiou]/’ as an array containing all the vowels? Somehow interprets the pattern?

If you want to find something specific but you’re not sure what, RegEx come in handy. The String#match method converts a pattern to a RegEx (if it isn’t one already) and then invokes its match method on the target String object. Here is how you find the characters from a String which are next to a whitespace:

'RubyMonk Is Pretty Brilliant'.match(/ ./)=>#<MatchData " I">

The pattern that .match uses in this case is (/ ./) to indicate a character preceded by a whitespace. (‘ .’) will also work because #match converts it into a RegEx

'RubyMonk Is Pretty Brilliant'.match(/ ./,10)

You can also pass a second argument to the match method. The second parameter of 10 specifies the position in the string to begin the search.

Looping - Using while and then giving a condition will run the loop as long as the while test is true. When while is false, the program will jump to end. While this thing is true, run the loop and when it is false jump to end.
* The do keyword can be used to initiate loops:

defring(bell,n)n.timesdobell.ringendend

This loop will run n number of times then stop

Literal. The term “literal” comes from the fact that you have written data literally into your program, i.e. exactly as written, not hidden behind a variable name. A literal is a notation for representing a fixed value in source code. It is some data that is presented directly in the code, rather than indirectly through a variable or function call. The data constituting a literal cannot be modified by a program, but it may be copied into a variable. When creating a variable and populating it with the integer 8, the variable is not a literal but the integer that it points to is? In the following, 1 is an integer literal and the three letter string in “cat” is a string literal:

inta=1;Strings="cat";

A literal is hard coded directly into source code as opposed to being called from or created in memory at run time.

each enumerable method and keyword do. ‘do’ is a keyword for creating loops in Ruby. String#each_char and Array#each call a block on to each character in the String or each element in the Array. The element or character must be represented in the block as a parameter in between the “double pipes” ||. do itself (concluded by end) contains the block of code.

Enumerable. A Ruby module (collection of methods and constants mixed into other classes. See module vs Class here: https://lh4.googleusercontent.com/e_Eml6aYg1udItOLjQCzUKF1L2K1JcjyZTnzYwcP7A=w1530-h800-no (Modules are about providing methods that you can use across multiple classes. Classes are about objects; modules are about functions.) ‘map’ and ‘each’ are inside enumerable. Enumerable is mixed into the Array and Hash classes.

Use map to get a modified array based on the code block. Use ‘each’ for its side effects (such as printing each element or pushing it into another array.)

A Range is a different class than Array but also mixes in enumerable. Range also works for strings?

Argument vs parameter - An argument is a single value to give to a method. For example for an array a.index("x") “x” is the argument. A parameter is like a mini variable that will given a new value when iterated over. For example a.each {|i| puts i} i is the parameter.