From f76ca0cd5ba03d5d5de72b24d99284f794a78cad Mon Sep 17 00:00:00 2001 From: Djalil Dreamski <32184973+dreamski21@users.noreply.github.com> Date: Sat, 9 Mar 2019 18:24:44 +0100 Subject: [PATCH] Corrected some js lines & typos & Fixed markdown --- README.md | 4 +- coding_conventions.md | 34 +++++------ functions.md | 83 +++++++++++++-------------- looping_and_control_statements.md | 56 +++++++++---------- primitives_and_other_basics.md | 93 +++++++++++++++++-------------- rails_introduction.md | 22 ++++---- ruby_oop_design.md | 84 ++++++++++++++-------------- 7 files changed, 190 insertions(+), 186 deletions(-) diff --git a/README.md b/README.md index df55637..99e6936 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -#Learning Ruby from a JavaScript background +# Learning Ruby from a JavaScript background This is purely a compilation of helpful notes for devs who are coming in to Ruby from **_JavaScript_**. Although the notes are tailored for a JavaScript developer, it could be useful for others. @@ -12,7 +12,7 @@ Please file an issue or a pull request if you see any inconsistencies or errors! [![forthebadge](http://forthebadge.com/images/badges/certified-snoop-lion.svg)](http://forthebadge.com) -##Topics: +## Topics: It is **highly** recommended that beginners move through these in the proposed order. diff --git a/coding_conventions.md b/coding_conventions.md index 3c0fab3..d8ce5b3 100644 --- a/coding_conventions.md +++ b/coding_conventions.md @@ -1,11 +1,11 @@ -#Coding Conventions +# Coding Conventions **THIS IS NOT A FULL GUIDE. JUST A GENERAL GUIDE FOR PURE BEGINNERS** A full set of coding conventions can be found at [bbatsov's writeup on Github here](https://github.com/bbatsov/ruby-style-guide) -##Curly Braces vs do...end +## Curly Braces vs do...end Most style guides and best practices state that: @@ -48,31 +48,31 @@ task :rake => (pre_rake_task { something }) See [Stackoverflow](http://stackoverflow.com/questions/5587264/do-end-vs-curly-braces-for-blocks-in-ruby) here for more details -##Naming convention -Unlike JS where many developers use ```CamelCase``` for their variable naming conventions, in Ruby: +## Naming convention +Unlike JS where many developers use ```camelCase``` for their variable naming conventions, in Ruby: * For plain variable names: use the ```snake_case``` convention. * For file and directory names, use the ```snake_case``` convention as well. * For constants, use the ```SCREAMING_SNAKE_CASE``` convention. * For Classes and Modules, use the ```CamelCase``` convention. -###Naming functions +### Naming functions -####Functions that return booleans +#### Functions that return booleans For functions that return a boolean value, the name should be suffixed with a ```?```. For example: ```ruby str.include? "substring" ``` -####Functions that are setters -In other languages like Java or C#, if we have an attribute ```name```, and we have to set the value of that attribute, then the setter function would be named ```setName``` +#### Functions that are setters +In other languages like Java or C#, if we have an attribute ```name```, and we have to set the value of that attribute, then the setter function would be named ```setName```. Ruby allows ```=``` in method names so the convention is to suffix the ```=``` with the attribute. So in this case, it would be: ```ruby def name=(value) - @name = value + @name = value end ``` @@ -81,14 +81,14 @@ Terse-tastic! For future reference, getter and setter functions are called _reader_ and _writer_ functions respectively in Ruby. -#####USE ```attr_accessor```/```attr_writer``` INSTEAD OF MANUALLY HAVING A SETTER +##### USE ```attr_accessor```/```attr_writer``` INSTEAD OF MANUALLY HAVING A SETTER -Most of the time, if this is a common instance variable, you do not need to set up your +Most of the time, if this is a common instance variable, you do not need to set up your ... -##Strings +## Strings -###String Concatenation vs String Formatting and Interpolation +### String Concatenation vs String Formatting and Interpolation ```ruby #bad @@ -103,14 +103,14 @@ email_with_name = "#{user.name} <#{user.email}>" email_with_name = format('%s <%s>', user.name, user.email) ``` -##Parentheses +## Parentheses In Ruby, parentheses are technically optional but there are times when it should be used to make the code more readable. According to the [unofficial Ruby style guide](https://github.com/bbatsov/ruby-style-guide), you **do NOT** use parentheses when: * It involves control flow statements (if-then, unless etc.) -* Its a class, function or uses any language specific "keywords" words like ```puts``` or ```attr_reader``` +* It's a class, function or uses any language specific "keywords" words like ```puts``` or ```attr_reader```. **You use parentheses for all other method invocations.** @@ -134,7 +134,7 @@ array.delete(e) bowling.score.should == 0 ``` -##Hashes +## Hashes Omit the ```{}``` when being called as the last parameter of a function: @@ -147,7 +147,7 @@ baz({ :key => 'value' }, 32) # good. The hash is not the last parameter so {} is ``` -##Chaining functions +## Chaining functions Functions can easily be chained as long as the reference to the class using ```self``` is returned from the functions diff --git a/functions.md b/functions.md index 1163647..604286e 100644 --- a/functions.md +++ b/functions.md @@ -1,13 +1,10 @@ -#JavaScript --> Ruby Cheatsheet +# Blocks, Procs, Lambdas and Functions -This is a simple cheatsheet/short guide of sorts for a JavaScript developer who wants to learn Ruby from scratch. - - -##Blocks, ```proc``` and ```lambda``` +## Blocks, ```proc``` and ```lambda``` In Ruby, there is a reusable piece of code called a block. It is designated by curly braces: ```{}``` -Many functions such as sort, each and times allow you to specify a code block to execute. +Many functions such as `sort`, `each` and `times` allow you to specify a code block to execute. For example, in Ruby, if you wanted to print "Hello" 5 times, you could do: @@ -16,23 +13,23 @@ For example, in Ruby, if you wanted to print "Hello" 5 times, you could do: 5.times { puts "Hello" } ``` -###Passing in code blocks as parameters to functions +### Passing in code blocks as parameters to functions If you want to pass in a code block as a valid parameter to a function, you need to specify to Ruby that it is a function/code block by using the ```&``` prefix. See below: **IMPORTANT:** Like the [splat arguments](#splat-arguments), this needs to be defined as a parameter of the function **last** ```ruby -#Note the '&' before the 'func' argument in the method definition +# Note the '&' before the 'func' argument in the method definition def foo(&func) func.call end foo { puts "Hello World" } ``` -###Isn't a block just an anonymous function? +### Isn't a block just an anonymous function? Not exactly. Blocks look VERY similar at a first glance but an anonymous function is more like a Ruby [lamda function](#lamda-functions) -###So...what is a ```proc```? +### So...what is a ```proc```? Ruby is built on an "everything is an object" philosophy and that ironically has a few exceptions, one of which is that **a block is NOT an object**. So how do we reuse blocks? We give it a name but a name can only be given to an object. This is where ```proc``` comes in. It is a container object that holds blocks. @@ -49,7 +46,7 @@ times_2 = Proc.new { |num| num * 2 } #define the proc # => [2,4,6] ``` -###Calling Procs directly with ```call``` +### Calling Procs directly with ```call``` To call procs directly, use the ```call``` method like so: @@ -79,7 +76,7 @@ So: ``` -###Converting Symbols to Procs for shorthand blocks +### Converting Symbols to Procs for shorthand blocks In Ruby, there is a bit of shorthand notations which will, for most JS developers not familair with Ruby, look like black magic. Converting symbols to Procs is one such example. See this example below: @@ -97,11 +94,11 @@ Everything is fairly normal until we hit the ```&:to_i``` What is happening is: -* ```to_i``` is a function and when combined with ```:``` gets turned into a symbol referencing the ```to_i``` function (which just converts the object to an integer) -* Recall that the ```&``` prefix for a proc usually unwraps/unpacks the block for a function to consume. In this case, since its a symbol and not a block, Ruby calls the ```to_proc``` function to convert it to a block. -* This newly formed block is fed into the map function +* ```to_i``` is a function and when combined with ```:``` gets turned into a symbol referencing the ```to_i``` function (which just converts the object to an integer). +* Recall that the ```&``` prefix for a proc usually unwraps/unpacks the block for a function to consume. In this case, since it's a symbol and not a block, Ruby calls the ```to_proc``` function to convert it to a block. +* This newly formed block is fed into the map function. -So....: +So...: ```ruby ["1", "2", "3"].map(&:to_i) # => [1,2,3] @@ -110,7 +107,7 @@ So....: **NOTE: This notation and referencing the method via ```&``` works with ```lambda``` (see next section) too.** -###What are lamdas? +### What are lamdas? A lambda is a ```proc``` but with a few small additions. It is declared almost the same way as a proc. ```ruby @@ -118,7 +115,7 @@ foo = Proc.new { puts "Hello World" } bar = lamda { puts "Goodbye Cruel World" } ``` -####Then aren't lambdas and procs the same? +#### Then aren't lambdas and procs the same? Nope. Lambdas and procs have 2 major differences: @@ -147,7 +144,7 @@ end bar # Returns 'Hello' not 11 ``` -####Why can't you call Procs and Lambda functions like regular functions with `()` +#### Why can't you call Procs and Lambda functions like regular functions with `()` If a lambda is defined like so: @@ -163,7 +160,7 @@ foo(5) # => NoMethodError: undefined method `foo` for Object This is better explained at [StackOverflow here](http://stackoverflow.com/questions/1686844/why-isnt-the-ruby-1-9-lambda-call-possible-without-the-dot-in-front-of-the-pare) -###Passing Procs/Lambdas as parameters to functions +### Passing Procs/Lambdas as parameters to functions To pass procs/lambdas as parameters to functions for actions such as filtering, use the ```&``` to refer to the proc/lambda. This essentially unpackages/unwraps the code block from the proc/lambda @@ -175,9 +172,9 @@ stuff.select!(&is_symbol) # => [:hello, :goodbye] ``` -##Functions and Parameters +## Functions and Parameters -###Defining functions +### Defining functions To define a function, the ```def``` keyword is used and is wrapped with an ```end``` to finish off the code block. @@ -199,7 +196,7 @@ def foo(name) end ``` -####Returning from a function +#### Returning from a function If you want to return something, you can use the ```return``` keyword. **HOWEVER**, if the last line of a function is the return statement, then the ```return``` keyword isn't needed. Ruby will automatically return the last variable set or retrieved without the return keyword. See below: @@ -209,7 +206,7 @@ def foo name = 'hello' return name #unnecessary return end -# + #good way to do it def foo name = 'hello' #Ruby will auto return this variable value. @@ -236,12 +233,12 @@ end ``` -####Functions with an arbitrary number of arguments using splat (```*```) +#### Functions with an arbitrary number of arguments using splat (```*```) In Java, you would define an arbitrary number of arguments of the same type via the ```...``` keyword like so: -```ruby -#in Java -public void function(int ... numbers) { ... } +```java +// In Java +public void function(int ...numbers) { /* do something */ } ``` In Ruby, the splat arguments keyword ```*``` is used. This tells ruby that *we don't know how many arguments there are. **We just know there is at least one*** @@ -257,7 +254,7 @@ todd_five("Innuendo Five!", "J.D", "Turk") ``` -###Executing functions with no parameters +### Executing functions with no parameters In JavaScript, it is mandatory to execute function with no arguments with parentheses but in ruby, parentheses aren't required and so most devs don't use them: @@ -265,7 +262,7 @@ In JavaScript, it is mandatory to execute function with no arguments with parent SomeClass.foo #This is equivalent to SomeClass.foo() in JS ``` -###Executing functions with one or more known parameters +### Executing functions with one or more known parameters Unlike JS, in Ruby, parameters don't need to be enclosed by parentheses. The Ruby intepreter just looks for the parameters to be seperated by commas. ```ruby @@ -274,25 +271,25 @@ puts('Hello', 'World') # Also correct in Ruby but less used as its unnec ``` -####When to use parentheses +#### When to use parentheses See the [Coding Conventions](coding_conventions.md#parentheses) page for more details. **tl;dr**: Omit parentheses for anything with keyword status in Ruby and explicitely use parentheses for everything else. -###Functions as arguments +### Functions as arguments In Ruby, functions can be passed blocks via {} which act similar to anonymous functions in JavaScript (see below) ```ruby books = {} books['stuff'] = 'hello' #setting a key and value is the same as in JS -books.values.each { puts 'Hello' } //equivalent to books.values.each(function(){ console.log('Hello') }); in JS +books.values.each { puts 'Hello' } #equivalent to Object.values(books).forEach(function(){ console.log('Hello') }); in JS ``` -###Functions doing changes inplace +### Functions doing changes inplace Some JS functions do their changes to an object in place and some don't. Ruby, however, makes this matter very clear. -Executing the function and ending with ! makes the change in-place. For example: +Executing the function and ending with `!` makes the change in-place. For example: ```ruby name = "Gautham" @@ -319,9 +316,9 @@ str = str.to_i #The workaround ``` -###Function parameters to anonymous functions +### Function parameters to anonymous functions -In Ruby, parameters to anonymous functions are enclosed via | or "pipe" characters like so: +In Ruby, parameters to anonymous functions are enclosed via `|` or "pipe" characters like so: ```ruby books.values.each { |book| puts 'Gotta read ' + book } @@ -329,18 +326,18 @@ books.values.each { |book| puts 'Gotta read ' + book } which is equivalent to in JavaScript: -```ruby -books.values.each(function(book) { +```javascript +Object.values(books).forEach(function(book) { console.log('Gotta read ' + book); }); ``` -###```yield``` and executing code blocks inside functions +### ```yield``` and executing code blocks inside functions In Ruby, you can yield control to run a block of code inside another function. This has a variety of uses. As a refresher, a block is just a reusable piece of code enclosed by braces ```{}``` -Using the ```yield``` you can invoke code blocks and pass it arguments as if they were functions. **Unless the blocks are specified as arguments, they are outside the parentheses. See below:** +Using the ```yield``` keyword you can invoke code blocks and pass it arguments as if they were functions. **Unless the blocks are specified as arguments, they are outside the parentheses. See below:** ```ruby def foo(greeting) @@ -353,11 +350,9 @@ foo("Top of the mornin to ya!") { |greeting| puts "#{greeting} John" } This prints out: -```ruby +``` Inside the function foo Top of the mornin to ya John Back inside the function foo ``` - - diff --git a/looping_and_control_statements.md b/looping_and_control_statements.md index 6ea8b37..c337b49 100644 --- a/looping_and_control_statements.md +++ b/looping_and_control_statements.md @@ -1,10 +1,10 @@ -#Looping and control statements +# Looping and control statements -###Conditional assignment +### Conditional assignment -In JS, we sometimes want to only set the value of a variable if its not already defined. To do that in JS, we would do something like this: +In JS, we sometimes want to only set the value of a variable if it's not already defined. To do that in JS, we would do something like this: -```ruby +```js some_var = some_var || {} ``` @@ -14,7 +14,7 @@ In Ruby, there is an even cooler and more terse way (Yey for terseness!). Here i some_var ||= {} #This is similar to a += or /= operator ``` -###```if``` keyword +### ```if``` keyword This works just like the JavaScript version but with one small enhancement: it can be used inline with other statements (in a very cool readable way). See below: @@ -22,7 +22,7 @@ This works just like the JavaScript version but with one small enhancement: it c puts "Hello Bruce" if name == 'Bruce' ``` -###```unless``` keyword +### ```unless``` keyword This is similar to the if condition except it will execute the statement if the result is **false** @@ -34,14 +34,14 @@ end # => "Hooray it's not 3!" ``` -You could also use the unless statement inline with other statements (in an almost backwards if statement). See below: +You could also use the unless statement inline with other statements (in an almost backwards `if` statement). See below: ```ruby -#Doing a type check to see if its an integer. The ? is just a naming convention to indicate it returns a boolean +#Doing a type check to see if it's an integer. The `?` is just a naming convention to indicate it returns a boolean puts "That's not an integer bro!" unless some_int.is_a? Integer ``` -###```switch```/```case``` statements +### ```switch```/```case``` statements What is called Switch statements in JS and Java and other languages is called simply case statements in Ruby. This in Ruby: @@ -69,25 +69,25 @@ end is equivalent to in JS: -```ruby -switch(language) { +```js +switch (language) { case "JS": - puts "Dat frotnend scripting language"; + console.log("Dat frotnend scripting language"); break; case "Java": - puts "Aw man. The kingdom of nouns!"; + console.log("Aw man. The kingdom of nouns!"); break; default: - "Some cool language I don't know!" + console.log("Some cool language I don't know!"); } ``` -So switch keyword in JS translates to case in Ruby - case keyword in JS translates to when in Ruby - default keyword in JS translates to else in Ruby +So **switch** keyword in JS translates to **case** in Ruby + **case** keyword in JS translates to **when** in Ruby + **default** keyword in JS translates to **else** in Ruby -###```for``` loops +### ```for``` loops unlike JS, Ruby has a different ```for``` syntax where it defines the range: @@ -107,7 +107,7 @@ for i in 0...10 # same as "for(var i = 0; i < 10; i++)" in JS. NOTE THE THREE DO end ``` -###Using the ```loop``` keyword (i.e do..while statement in JS) +### Using the ```loop``` keyword (i.e do..while statement in JS) In Ruby, there is another way to loop through code called the ```loop``` statement. It takes in a code block and asks for a condition to exit out of the loop if the condition is met with the ```break``` keyword. @@ -125,9 +125,9 @@ loop do end ``` -This is equivalent to this do..while in JS: +This is equivalent to this `do..while` in JS: -```ruby +```js var i = 0; do { i += 1; @@ -135,7 +135,7 @@ do { } while (i > 9); ``` -###Using ```until``` keyword in a ```while``` loop +### Using ```until``` keyword in a ```while``` loop Just like how the ```unless``` keyword is the opposite of the ```if``` statement, the ```while``` also has its opposite: ```until```. It is used in a similar way to ```unless```. @@ -149,7 +149,7 @@ end ``` -####Using the ```next``` keyword in loop +#### Using the ```next``` keyword in loop You can use the 'next' keyword to skip the loop if a condition is met. It is equivalent to the ```continue``` keyword used in combination with an if. @@ -164,7 +164,7 @@ end Equivalent to JS's continue used with an if statement: -```ruby +```js for (var i = 0; i <= 5; i++) { if (i % 2 == 0) { continue; @@ -173,9 +173,9 @@ for (var i = 0; i <= 5; i++) { } ``` -###Using the ```each``` iterator for looping +### Using the ```each``` iterator for looping -The each iterator is similar to the Array's each() or Underscore/Lodash's _.each function. +The each iterator is similar to the Array's `.forEach()` or Underscore/Lodash's `_.each` function. You specify an object to loop through and then specify a code block to run for each item in the object. @@ -194,7 +194,7 @@ is equivalent to in JS: ```javascript var object = ['hello', 'goodbye']; -object.each(function(str) { +object.forEach(function(str) { console.log(str); }); ``` @@ -223,7 +223,7 @@ person.each { |key_or_val| puts |key_or_val| } The reason for this is due to the way the iterator is setup for the each. -###Using ```times``` iterator for simple looping +### Using ```times``` iterator for simple looping If you want to make a block of code execute a fixed number of times, the best way to do it would be through a "times" loop diff --git a/primitives_and_other_basics.md b/primitives_and_other_basics.md index bde8f9e..6308cdf 100644 --- a/primitives_and_other_basics.md +++ b/primitives_and_other_basics.md @@ -1,8 +1,8 @@ -#Basic Primitive Types and Reading/Writing to Screen +# Basic Primitive Types and Reading/Writing to Screen **Disclaimer**: This doesn't go through every single primitive type and explain what it is. It just explains the differences between how it is implemented and used in JS vs Ruby. -##Comments +## Comments Single line comments in Ruby are defined via: @@ -20,7 +20,7 @@ comment =end ``` -##Semicolons +## Semicolons Semicolons are not necessary and not recommended to be used unless you have multiple statements of code onto one line. @@ -35,9 +35,9 @@ puts 'goodbye cruel world'; puts 'hello world'; puts 'goodbye cruel world'; ``` -##Reading and Writing to the Screen/Console +## Reading and Writing to the Screen/Console -###Print vs puts +### Print vs puts In JavaScript, to print something to the console, you can use the ```Console``` object via ```console.log``` but in Ruby, it is differentiated to two different functions: ```puts``` and ```print``` The differences are **exactly the same as** Java's ```System.out.println``` and ```System.out.print``` respectively in that: @@ -62,7 +62,7 @@ print 'Hello' puts 'Hello' ``` -###Referencing Variables in Puts/Print +### Referencing Variables in Puts/Print To reference variables already defined, use the ```#{variable_name}```. For example: @@ -71,8 +71,8 @@ name = 'Gautham' puts 'Hello #{name}' ``` -###Getting User Input from console -In Ruby, to read input from the user, its with the ```gets``` keyword (puts for output, gets for input). +### Getting User Input from console +In Ruby, reading input from the user is done with the ```gets``` keyword (puts for output, gets for input). There is one caveat to the ```gets``` keyword and that it returns the User's input WITH a newline character. @@ -81,7 +81,7 @@ puts "Hello. What is your name?" name = gets # If you entered 'Jake', then name='Jake\n' ``` -####Removing the newline character from ```gets``` +#### Removing the newline character from ```gets``` To remove the newline character added from ```gets```, use the ```chomp``` function. ```ruby @@ -89,11 +89,11 @@ name = gets.chomp # With chomp, it strips the '\n' and so name='Jake' ``` -##Hashes (i.e JS-y objects) +## Hashes (i.e JS-y objects) Objects in JavaScript are called hashes in Ruby. -###Traditional/JS-y way to define it: +### Traditional/JS-y way to define it: In JS and Ruby, an empty hash can be defined like so: @@ -114,7 +114,7 @@ a = { status: 'zombie', name:'Katie', id: 5 } a[:status] #Same as a['status'] ``` -####Alternate notation for key value seperators using the hashrocket: ```=>``` +#### Alternate notation for key value seperators using the hashrocket: ```=>``` Instead of using ```:``` to seperate key value pairs, In Ruby, one can also use ```=>``` instead. @@ -122,20 +122,21 @@ Instead of using ```:``` to seperate key value pairs, In Ruby, one can also use ```ruby stuff = { - 'name' => 'Bilbo Baggins', - 'survives' => true + 'name' => 'Bilbo Baggins', + 'survives' => true } ``` + Equivalent JS: ```javascript stuff = { - name: 'Bilbo Baggins', - survives: true + name: 'Bilbo Baggins', + survives: true }; ``` -####Ommitting the ```{}``` +#### Ommitting the ```{}``` When passing a hash to a function, if the hash is the last parameter, the ```{}``` can be ommitted. @@ -146,7 +147,7 @@ foo({ 'status' => 'zombie' }) # This... foo('status' => 'zombie') # is the same as this ``` -###via Hash.new: +### Via Hash.new: Hash.new takes in an optional parameter for the default value. If set, anytime a non-existent key is accessed or an operation is done on a key that has no value, this default value is returned instead. @@ -159,7 +160,7 @@ puts stuff[a] # prints out "3" puts stuff[b] # prints out "0" ``` -####Dot notation and Ruby +#### Dot notation and Ruby Unlike JavaScript where objects (i.e Ruby hashes) can be accessed by dot notation, Ruby forces hash properties to be accessed via *array notation*. @@ -184,11 +185,11 @@ foo.bar # Invalid. Looks for a function named bar that belongs to foo and thr ``` -##Strings +## Strings Strings works pretty much the same way in JS as it does in Ruby with a few nice enhancements. -###String Interpolation +### String Interpolation Aside from standard string concatenation, Ruby allows something called String interpolation. This allows you to refer to variables from inside a string using the ```#{}``` syntax: ```ruby @@ -202,7 +203,16 @@ You can even execute functions from inside the ```#{}``` puts "#{name.upcase}" # => BATMAN ``` -###String Interpolation and Single Quotes +ES2015 has introduced Template literals (aka template strings) which are the equivalent to Ruby's String interpolation: + +```javascript +name = 'Batman' +console.log(`${name}`) // => Batman + +console.log(`${name.toUpperCase()}`) // => BATMAN +``` + +### String Interpolation and Single Quotes String interpolation is not possible with single quotes. If single quotes are specified, Ruby will take the input **literally**. **You MUST use double quotes for string interpolation to be done** @@ -213,7 +223,7 @@ puts 'I am #{name}' # => 'I am #{name}' puts "I am #{name}" # => 'I am Batman' ``` -##Arrays +## Arrays Arrays work the same as in JS with one or two small tweaks. @@ -225,18 +235,18 @@ In Ruby, there is an alias for the push function using the ```<<``` operator. It ``` -##Comparing/Converting/Checking different objects +## Comparing/Converting/Checking different objects -###Comparing two different objects +### Comparing two different objects -###```==``` operator -The JS ```===``` is the same as ```==``` in that it checks **both** the type and the **value** **BUT does not care if they are in two different locations in memory (unlike Java's ==)**. +### ```==``` operator +The JS ```===``` is the same as Ruby's ```==``` in that it checks **both** the type and the **value** **BUT does not care if they are in two different locations in memory (unlike Java's ==)**. -###```===``` operator +### ```===``` operator This is the same as ```==``` except it can be overriden by objects for their own custom equals logic. It would be the equivalent to overriding the equals function in Java. -###Combined Comparison Operator +### Combined Comparison Operator Aside from the usual ```==```, ```>=```, ```<=```, ```!=```, Ruby has another comparison operator called the **Combined Comparison Operator** designated by ```<=>```. @@ -251,17 +261,17 @@ In this regard, you can think of the combined comparison operator as a glorified ```ruby 'Hello' <=> 'Hello' # => 0 3 <=> 2 # => 1 -3 <=> 9 # => -1 +3 <=> 9 # => -1 ``` -###```equal?``` function +### ```equal?``` function To check to make sure that the two objects point to the same point in memory, you need to use the ```equal?``` **See this [StackOverflow answer on == vs === vs equal? vs eql?](http://stackoverflow.com/a/7157051)** -###Checking Types +### Checking Types To check the type of an object, use ```is_a?``` function ```ruby @@ -270,32 +280,33 @@ greeting.is_a? Integer # Checking if greeting is an Integer. => false greeting.is_a? String # Checking if greeting is a String. => true ``` -###Converting +### Converting -####To a string +#### To a string Converting to a String involves using the ```to_s``` function ```ruby 3.to_s # => "3" ``` -####To an integer +#### To an integer Involves using the ```to_i``` function ```ruby 'Hello'.to_i # => 0 ``` -####To a proc +#### To a proc Involves using the ```to_proc``` function Procs are covered [here](functions.md#blocks-procs-and-lambdas). -##Symbols +## Symbols **Symbols are a special object that contains names and strings inside the Ruby Interpreter.** -There is no standard JS equivalent to Symbols. The closest Java equivalent to this would probably interned Strings. This is because symbols are defined as static things which are used once and are immutable. Referencing them again will refer to the same copy in memory. +~~There is no standard JS equivalent to Symbols~~. Symbols were introduced to JavaScript in ES2015. +The closest Java equivalent to this would probably be interned Strings. This is because symbols are defined as static things which are used once and are immutable. Referencing them again will refer to the same copy in memory. Symbols can only be values set to other objects. @@ -313,15 +324,15 @@ books['some-other-book'] = :hello # Refers to the SAME object as books['some-boo **WARNING: *For Ruby versions < 2.2*, SYMBOLS TAKE UP MEMORY AND CANNOT BE GARBAGE COLLECTED. YOU CAN CAUSE DoS PROBLEMS IF YOU AREN'T CAREFUL** -##Decrementing and Incrementing +## Incrementing and Decrementing Unlike JS, Ruby has no preincrement ```++i```, postincrement ```i++```, predecrement ```--i``` and postdecrement ```i--``` for the same reasons as python: * Makes implementation simpler -* ++ and -- are NOT reserved operator in Ruby. +* ++ and -- are NOT reserved operators in Ruby. * C's increment/decrement operators are in fact hidden assignment. They affect variables, not objects. You cannot accomplish assignment via method. -So instead, Ruby uses +=/-= operator +So instead, Ruby uses += and -= operators ```ruby i++ # throws an error in Ruby diff --git a/rails_introduction.md b/rails_introduction.md index 0501387..1730364 100644 --- a/rails_introduction.md +++ b/rails_introduction.md @@ -1,4 +1,4 @@ -#Rails introduction +# Rails introduction Rails is a great MVC framework written on top of Ruby. @@ -6,13 +6,13 @@ This is not an exhaustive guide. Not even close. For full docs, go [here](http:/ Right now, this guide is wholly unfinished. -##Basic Terminal Commands +## Basic Terminal Commands All commands can be run with ```-h``` or ```---help``` to list more information. For a full guide, see [Rails Official Commandline Guide](http://guides.rubyonrails.org/command_line.html) -###Rails commands +### Rails commands To create a new app, use the command @@ -31,7 +31,7 @@ To interact with the rails app from command line, you can use the rails console ```rails console``` -####Generating Models +#### Generating Models To generate a new model, the command is: @@ -70,7 +70,7 @@ Now to create the table, run the command: ```rake db:migrate``` -###Rake commands +### Rake commands What is Rake? Rake is simply a build tool. It can be thought of as a Makefile with Ruby code. Rake is a superset of Ruby. It allows developers to define build tasks via the `task` keyword. @@ -106,7 +106,7 @@ welcome_index GET /welcome/index(.:format) welcome#index ``` -##Basic Structure of a Rails app +## Basic Structure of a Rails app @@ -172,9 +172,9 @@ welcome_index GET /welcome/index(.:format) welcome#index
-##Routing +## Routing -###Configuring Routes +### Configuring Routes A list of all routes in an application can be found in ```config/routes.rb``` @@ -191,7 +191,7 @@ To specify the root (i.e default controller and action for route: ```/```), then ```root '#``` -###Configuring resources +### Configuring resources For data to be queried back and forth by your application to serve the user, there need to be REST endpoints set up for the resources. @@ -237,7 +237,7 @@ welcome_index GET /welcome/index(.:format) welcome#index -##Naming Convention +## Naming Convention Given the database table name ```tweets``` with the data below: @@ -269,7 +269,7 @@ In other words, the models in rails use a singular name while the actual corresp -##Glossary +## Glossary * ```DSL``` - Domain Specific Language * ```resource```- an object/collection of objects that can be queried by the user via REST. diff --git a/ruby_oop_design.md b/ruby_oop_design.md index 00867da..c3cc5b2 100644 --- a/ruby_oop_design.md +++ b/ruby_oop_design.md @@ -1,10 +1,8 @@ -#Ruby OOP Design +# Ruby OOP Design -#Everything is an object +*Everything is an object*. One of the fundamental tenets of Ruby is that *EVERYTHING* is an object. You will see this further in the classes section. -One of the fundamental tenets of Ruby is that *EVERYTHING* is an object. You will see this further in the classes section. - -#Classes +## Classes Unlike JS which needs to use closures to create class-like structures (at least until EcmaScript 6 is finalized and comes out), Ruby has an actual structure designated by the ```class``` attribute. @@ -13,10 +11,10 @@ Here are the basic syntaxes for a class: 1. ```class``` defines the class (pretty obvious) 2. ```initialize``` function is the constructor for the class. The name matters. The constructor MUST have this name if you are overriding the default empty constructor! 3. An instance variable must have the ```@``` prefixed to it (Example: _@name_) -4. To instantiate an instance of a class, unlike JS which uses ```new (...)```, Ruby uses a syntax with this format: ```.new(...)``` +4. To instantiate an instance of a class, unlike JS which uses ```new (...)```, Ruby uses a syntax with this format: ```.new(...)``` 5. ```self``` is a term to refer to the actual class itself NOT the instance of the class. -Finally, Class names are written in `CamelCase` not ```snake_case``` +Finally, Class names are written in `CamelCase` not ```snake_case```. Here is a simplistic example: @@ -37,7 +35,7 @@ batman = Superhero.new('Batman', 'Bruce Wayne') batman.description # => "I'm Batman but my real name is Bruce Wayne" ``` -###Inheritence +### Inheritence Unlike JS which uses a nonstandard prototypal inheritence, Ruby has a more classic inheritence akin to Java. It uses the ```<``` to designate what the class inherits from. @@ -69,11 +67,11 @@ As you can see, the Agent class has two functions and by using the ```child_clas **Ruby only allows single parent inheritence. To get around this, see [here](#mixins-with-include-and-extend) -###Overriding inherited functions +### Overriding inherited functions This is just like all other languages, just name the function the same as in the parent class to override it. -###Calling super (superclass version) function +### Calling super (superclass version) function If you have overriden a parent class function but now still need access to the parent class function, you can use the ```super``` keyword like you would in Java. @@ -87,12 +85,12 @@ end class Pitbull < Dog def speak super #If there were any arguments, it would be super(...) - puts 'But I'm also a pitbull...' + puts "But I'm also a pitbull..." end end ``` -###Getters and Setter functions +### Getters and Setter functions Getter and setter functions can be created via standard function definitions but this is suboptimal. We don't want to create getters and setters manually for a lot of the instance variables. Ruby allows a nice shortcut for this using the ```attr_reader```, ```attr_writer``` and ```attr_accessor``` classes! They take in the instance variable name structured as a symbol (see example below). @@ -132,7 +130,7 @@ a.name # => 'Billy' If you are confused about the ```name=(value)``` then please see [the naming convention entry in the Coding Conventions page](coding_conventions.md#setter-naming-convention) -###Class Definitions (Gotchas when coming from other languages) +### Class Definitions (Gotchas when coming from other languages) In Ruby, code that defines a class is no different from any other code. This means you can place the class definition code almost anywhere. For example: @@ -148,9 +146,9 @@ In Ruby, code that defines a class is no different from any other code. This mea end ``` -#####Classes can be defined multiple times +##### Classes can be defined multiple times -In Ruby, the first time the interpreter encounters a class definition, it creates the class with the specific members that have been specified. If it encounters a definition for the same class again, it actually *extends the existing definition* +In Ruby, the first time the interpreter encounters a class definition, it creates the class with the specific members that have been specified. If it encounters a definition for the same class again, it actually *extends the existing definition*. ```ruby # Defines class Foo @@ -183,11 +181,11 @@ This metaprogramming feature is a pretty powerful way to extend classes at runti The JS equivalent of this would be overriding the `prototype` of an existing type. -######Careful in overriding existing functions! +###### Careful in overriding existing functions! -This kind of extending classes on existing types inherent to the language is known by JS devs as `monkeypatching` and is dangerous to do on existing types. For example: +This kind of extending classes on existing types inherent to the language is termed by JS devs as "monkeypatching" and is dangerous to do on existing types. For example: -``` +```ruby class Foo def bar 3 @@ -207,15 +205,15 @@ Foo.new.bar # => 5 This example might seem silly but it is very important to note. In JavaScript, developers are warned not to overwrite existing types like `String.prototype` or `Array.prototype` that might unintentionally affect other functionality or libraries used in the app. Ruby code has the same implications and so the same care must be taken. -###Scope +### Scope JavaScript is a wonderful language in the way we can manipulate access to variables via closures. In Ruby, the scoping rules completely different. -Unlike JS which is all based on a function scope, this has 4 different scopes: +Unlike JS which is all based on a function scope, Ruby has 4 different scopes: -1. **global variables (prefixed with ```$```)** - are available everywhere. _If you don't prefix the variable with ```$``` but it is outside of any function or class, then it is still a global variable. -2. **local variables** - are available only to the methods they are defined in -3. **class variables (prefixed with ```@@```)** - are available to all members of the class and between instances of the class. Adding a class variable is essentially like attaching a variable to a JavaScript object's prototype. As soon as its defined, it is shared and viewed by all instances of the object. +1. **global variables (prefixed with ```$```)** - are available everywhere. _If you don't prefix the variable with ```$``` but it is outside of any function or class, then it is still a global variable_. +2. **local variables** - are available only to the methods they are defined in. +3. **class variables (prefixed with ```@@```)** - are available to all members of the class and between instances of the class. Adding a class variable is essentially like attaching a variable to a JavaScript object's prototype. As soon as it's defined, it is shared and viewed by all instances of the object. 4. **instance variables (prefixed with ```@```)** - are available to a particular instance of the class **NOTE:** To access a global variable defined with ```$```, it **MUST** be accessed with ```$``` as the prefix. @@ -244,7 +242,7 @@ b = Foo.new puts Foo.get_instance_count # => 2 ``` -###Everything is an object (even a class) +### Everything is an object (even a class) If you define a class Foo: @@ -264,13 +262,13 @@ BasicObject <--- Object <-- Module <-- Class So technically... all classes are modules and `BasicObject` is the root of the Ruby class heirarchy. -###Class Reflection and Metaprogramming +### Class Reflection and Metaprogramming Unlike other languages like C where much of the metadata on an object or class is stripped away during runtime, Ruby keeps almost all of it. Some useful information that can be available are: -#####Class and Superclass via `.class` and `.superclass` +##### Class and Superclass via `.class` and `.superclass` ```ruby class Foo @@ -283,7 +281,7 @@ x.superclass # => Class Every object has a `class` property that is essentially a reference to the class that created it. In the aforementioned example, `x.class == Foo` -#####Getting a list of methods via `.methods`, `.public_methods`, `.protected_methods`, `.private_methods` +##### Getting a list of methods via `.methods`, `.public_methods`, `.protected_methods`, `.private_methods` ```ruby class Foo @@ -292,14 +290,14 @@ class Foo end x = Foo.new -x.methods(false) # false tells the function to only return non-inherited methods. +x.methods(false) # `false` tells the function to only return non-inherited methods. # => [:bar] #To get a subset by searching through the methods, calling grep() is useful x.methods.grep(/ba/) # => [:bar] ``` -#####Getting a list of instance variables via `.instance_variables` +##### Getting a list of instance variables via `.instance_variables` ```ruby class Foo @@ -313,10 +311,10 @@ Foo.instance_variables # => [:@a] Foo.new.instance_variables # => [:@b] ``` -Why is `@a` not available for `Foo.new`? Its because` @a` is an instance variable of Foo (since class Foo is technically an object). When `Foo.new` is executed, the `initialize` function is called, creating a new instance variable `@b`. +Why is `@a` not available for `Foo.new`? It's because` @a` is an instance variable of Foo (since class Foo is technically an object). When `Foo.new` is executed, the `initialize` function is called, creating a new instance variable `@b`. -#Module +## Module A module in Ruby is a data structure for holding methods and constants. @@ -328,11 +326,11 @@ module Foo end ``` -##Namespace resolution using ``::`` +### Namespace resolution using ``::`` If there are multiple functions with the same name in different modules, to make sure Ruby knows to pick the right function, we use ```::``` format to be specific. -For example. if you define a module with the constant PI +For example, if you define a module with the constant PI ```ruby module Foo @@ -354,7 +352,7 @@ Date.Today #same as Date::Today ``` -##Importing a module with ```require``` and ```include``` +### Importing a module with ```require``` and ```include``` There are two ways to import a module: @@ -380,9 +378,9 @@ class Foo end ``` -##Mixins +### Mixins -###Mixin with ```include``` +#### Mixin with ```include``` When you use ```include```, the module's methods act as if they are now part of the **instance of the** class/module and this has far reaching effects. See below: @@ -415,10 +413,10 @@ gavrillo.shoot("Franz Ferdinand") # => 'Shot Franz Ferdinand' This is how single inheritence can be side stepped. Classes can be mixed in and inherited and the child classes would then inherit the constants and methods of the module even if they aren't explicitely inclduing it themselves. -###Mixin with ```extend``` -The mixin with ```extend``` works exactly the same way as the [mixin with include](#mixins-with-include) but it works on a **Class level** +#### Mixin with ```extend``` +The mixin with ```extend``` works exactly the same way as the [mixin with include](#mixins-with-include) but it works on a **Class level**. -See example below (thanks code academy for the example): +See example below (thanks Codeacademy for the example): ```ruby module ThePresent @@ -436,13 +434,13 @@ TheHereAnd.now Note how the class itself can call ```now``` and not just instances of the class. -#Constants +## Constants In Ruby, any reference that begins with an uppercase letter whether its a variable, a class name or module name is a constant. Unlike other languages, in Ruby, constants can have their values set after they have already been initialized. -A ruby constant is different from a regular variable in only 1 way: *Scope*. +A Ruby constant is different from a regular variable in only 1 way: *Scope*. See the following: @@ -466,12 +464,12 @@ Foo::SomeConstant # => hello Foo::Bar::SomeConstant # => bye ``` -###Accessing constants and nesting during runtime +### Accessing constants and nesting during runtime If constants of a specific module need to be accessed, then the `constants` keyword is used: ```ruby -Module Foo +module Foo SomeConstant = 'hello' end