├── Active Record Concerns.md ├── Angular Binding Issues.md ├── Recursive Decomposition.md ├── Notes & Settings ├── Angular Model Screencast.md ├── Interview Notes.md ├── Notes & Settings (air-2's conflicted copy 2013-12-17) ├── Notes & Settings (EDM-Mac683's conflicted copy 2014-05-28) ├── Scope() && Isolate Scope() Getter Methods.md ├── Preforking Server.md ├── Exponentiation.md ├── Filters.md ├── Overriding Rails Accessor Methods.md ├── Computer Networks Coursera- Goals and Motivation.md ├── pwd.md ├── Computer Networks- Protocols and Layering.md ├── Backbone MVC Architecture.md ├── 10,000 Hours.md ├── Rails Root.md ├── Javascript RegExes.md ├── Composition.md ├── Computer Networks- Statistical Multiplexing.md ├── Recurrence Relation.md ├── Naming Migrations.md ├── Route Globbing.md ├── Direct versus Indirect Inputs.md ├── Gem Locking.md ├── Fetch vs. Key Lookup.md ├── Struts.md ├── MongoDB Scaling.md ├── Gems.md ├── Chameleon.md ├── Concatenating Regular Expressions in Javascript.md ├── Common Backbone Errors.md ├── type, which, and whereis.md ├── Javascript Inheritance.md ├── Array Style.md ├── Javascript Metaprogramming.md ├── REST Constraint - Client-Server Separation.md ├── Rack.md ├── Ruby Hook Methods.md ├── Annotate Models.md ├── REST Constraint- Statelessness.md ├── Serializing Rails Attributes.md ├── Sublime Snippets.md ├── Computer Networks- The Physical Layer - Media.md ├── MongoDB Replica Sets.md ├── Continuation-Passing Style.md ├── MongoDB Capped Collections.md ├── Rails Env.md ├── Event-Driven Javascript.md ├── Computer Networks- The Physical Layer- Types of Media.md ├── RSpec.md ├── Ruby Regexes.md ├── Database Sandboxing.md ├── Automate Tests with Guard.md ├── Seed.md ├── Scoping Routes.md ├── Database Indices.md ├── Indexing AJAX Applications.md ├── Postgres.md ├── Unix Processes.md ├── Symlink.md ├── Best Practices for Backbone Templating.md ├── Named Routes.md ├── Unix Command Substitution.md ├── Conditionally Apply Classes with ng-class.md ├── Yeoman.md ├── Input Roles.md ├── Vim Commands.md ├── Collection+JSON.md ├── Websocket.md ├── MEAN.io.md ├── Localhost.md ├── Partials.md ├── Angular Isolate Scopes.md ├── Functional Programming in Ruby and JavaScript.md ├── Dotfiles.md ├── Computer Networks Coursera- Sockets.md ├── Ruby Sort By.md ├── Git Log.md ├── Blocks.md ├── By Value versus By Reference.md ├── Websockets vs TCP Sockets.md ├── Logarithms and Fast Exponentiation.md ├── Mongoose Callbacks.md ├── State Machines.md ├── Pure Function.md ├── Haskell List Comprehensions.md ├── Kestrel.md ├── Function Currying.md ├── Regex Cheat Sheet.md ├── Automating Front-end Workflows.md ├── Insertion Sort.md ├── Encrypting Passwords.md ├── IIFEs in Coffeescript.md ├── Rails Middleware.md ├── Creating A Good GitHub Page.md ├── Database Speed vs Durability.md ├── Prototypal Inheritance.md ├── Javascript Type Checking.md ├── Domain-Specific API Design.md ├── Array Iterators.md ├── Javascript Recipe Cheat Sheet.md ├── Null Object Pattern.md ├── Node.md ├── Machine Language.md ├── Ruby Blocks.md ├── String Literals.md ├── Object-Oriented Programming.md ├── Underscore Templating.md ├── Symbols.md ├── Inverse Associations.md ├── Bash_profile vs bash_rc.md ├── Observer Pattern.md ├── Angular Directives - Advanced.md ├── Rails Views Cheat Sheet.md ├── Angular Forms.md ├── Chameleon Template (Chameleon README).md ├── Logarithms And Bits.md ├── Truthy and Falsy.md ├── Migrations.md ├── Node.js Modules.md ├── Capybara Cheat Sheet.md ├── Starting A Git Project.md ├── Logarithms And Trees.md ├── Higher Order Functions.md ├── Javascript Ninjahood.md ├── Template Method Pattern in Angular Templates.md ├── Angular Minification.md ├── Event-Driven, Asynchronous Callbacks.md ├── Writing Acceptance Tests in Capybara.md ├── README.md ├── Angular Filters.md ├── Angular as MVVM.md ├── Namespaced Routes.md ├── Setting Up RSpec.md ├── Active Record Referential Integrity.md ├── Git Merging.md ├── Composite Literal Syntax.md ├── API.md ├── Angular Initialization.md ├── Rspec Before vs Let.md ├── Unix File Permissions.md ├── Use SVG for Infinite Image Scalability.md ├── Test Driven Angular.md ├── Barewords.md ├── Patterns of Enterprise Architecture.md ├── Angular Models.md └── Array Methods.md /Active Record Concerns.md: -------------------------------------------------------------------------------- 1 | # Active Record Concerns 2 | 3 | -------------------------------------------------------------------------------- /Angular Binding Issues.md: -------------------------------------------------------------------------------- 1 | # Angular Binding Issues 2 | 3 | -------------------------------------------------------------------------------- /Recursive Decomposition.md: -------------------------------------------------------------------------------- 1 | # Recursive Decomposition 2 | 3 | -------------------------------------------------------------------------------- /Notes & Settings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brettshollenberger/codecabulary/HEAD/Notes & Settings -------------------------------------------------------------------------------- /Angular Model Screencast.md: -------------------------------------------------------------------------------- 1 | # Angular Model Screencast 2 | 3 | * Objects should manage their data, not controllers 4 | * -------------------------------------------------------------------------------- /Interview Notes.md: -------------------------------------------------------------------------------- 1 | * Pick out my blogs 2 | * Focus on teamwork element --helping others to succeed 3 | * Software is about communication 4 | 5 | -------------------------------------------------------------------------------- /Notes & Settings (air-2's conflicted copy 2013-12-17): -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brettshollenberger/codecabulary/HEAD/Notes & Settings (air-2's conflicted copy 2013-12-17) -------------------------------------------------------------------------------- /Notes & Settings (EDM-Mac683's conflicted copy 2014-05-28): -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brettshollenberger/codecabulary/HEAD/Notes & Settings (EDM-Mac683's conflicted copy 2014-05-28) -------------------------------------------------------------------------------- /Scope() && Isolate Scope() Getter Methods.md: -------------------------------------------------------------------------------- 1 | # Scope() && Isolate Scope() Getter Methods 2 | 3 | template.isolateScope() -> return isolate scope of the template 4 | template.scope() -> returns the scope the template was compiled with? -------------------------------------------------------------------------------- /Preforking Server.md: -------------------------------------------------------------------------------- 1 | # Preforking Server 2 | 3 | @(UNIX)[UNIX|Forking|System Calls] 4 | 5 | In order to save on the overhead required to fork a process, a pre-forking server forks off a pool of child processes, each of which sits waiting for work to come in. -------------------------------------------------------------------------------- /Exponentiation.md: -------------------------------------------------------------------------------- 1 | # Exponentiation Algorithms 2 | 3 | O(logn): 4 | 5 | class Integer 6 | def pow(n) 7 | pow_iter(1, self, n) 8 | end 9 | 10 | def pow_iter(total, base, count) 11 | return total if count == 0 12 | pow_iter(total * base, base, count-1) 13 | end 14 | end -------------------------------------------------------------------------------- /Filters.md: -------------------------------------------------------------------------------- 1 | | filter:{formatted: startDate.date}:min 2 | | filter:{formatted: endDate.date}:max 3 | 4 | $scope.min = function(actual, expected) { 5 | return actual >= expected; 6 | }; 7 | 8 | $scope.max = function(actual, expected) { 9 | return actual <= expected; 10 | }; 11 | 12 | -------------------------------------------------------------------------------- /Overriding Rails Accessor Methods.md: -------------------------------------------------------------------------------- 1 | # Overriding Rails Accessor Methods 2 | 3 | With ActiveRecord, we can override the accessor methods to provide reasonable defaults: 4 | 5 | class SillyFortuneCookie < ActiveRecord::Base 6 | 7 | def text 8 | self[:text] || 'n/a' 9 | end 10 | 11 | def text=(value) 12 | self[:text] = value + " in bed" 13 | end 14 | end -------------------------------------------------------------------------------- /Computer Networks Coursera- Goals and Motivation.md: -------------------------------------------------------------------------------- 1 | # Computer Networks: Goals and Motivation 2 | 3 | Types of Networking Courses: 4 | 5 | * Communications - Focus on signals: how we carry information in bits across networks 6 | * Networking - Focus on packets 7 | * Distributed systems: Focus on apps that can be built on top of networks 8 | 9 | This Coursera course is on Networking -- the middle layer -- how packets are transferred across networks. -------------------------------------------------------------------------------- /pwd.md: -------------------------------------------------------------------------------- 1 | # pwd 2 | 3 | `pwd` is a built-in command in bash, zsh, ksh, and other common shells that's used to _print_ the _working directory_ (hence `pwd`). 4 | 5 | $ pwd 6 | /Users/brettshollenberger 7 | 8 | #### Options 9 | 10 | $ pwd -L 11 | 12 | Prints your logical path; this option is passed by default. 13 | 14 | $ pwd -P 15 | 16 | Prints your physical location, which may differ from your logical path if you've followed a symlink. -------------------------------------------------------------------------------- /Computer Networks- Protocols and Layering.md: -------------------------------------------------------------------------------- 1 | # Computer Networks: Protocols and Layering 2 | 3 | Networks need modularity to manage complexity, the same way a webapp must be modular to manage complexity. 4 | 5 | Networks have many concerns: 6 | 7 | * Make and break connections 8 | * Find a path through the network 9 | * Transfer information reliably 10 | * Transfer arbitrary length information 11 | * Send as fast as the network allows 12 | * Share bandwidth among users 13 | * Secure information in transit 14 | * Add new hosts to the network -------------------------------------------------------------------------------- /Backbone MVC Architecture.md: -------------------------------------------------------------------------------- 1 | # Backbone.js MVC Architecture 2 | 3 | Like other front-end frameworks, Backbone uses the Front Controller design pattern, which layers the MVC stack behind a single point of entry. The Front Controller handles routing, pairing HTTP requests with controller actions, and passing off the request to the appropriate controller. 4 | 5 | Similar to Rails & Django, the controller action then interacts with the model to get the data it requires, loads the appropriate view, injects the model data into the view, and returns the HTTP response to the browser. -------------------------------------------------------------------------------- /10,000 Hours.md: -------------------------------------------------------------------------------- 1 | # Brett's Rules for Reaching 10,000 Hours 2 | 3 | * Patience is the most important part of the process 4 | * At hour 1,000, (give or take), you will lose your patience. Your mantra for this day, and proceeding day you feel impatient is this: 5 | 6 | > Today I will learn something small, and learn it well. Perhaps I will practice something I already know, and need to work at to improve. What I do today will feel like pouring a glass of water into the lake of knowledge I've acquired, but every glass is as important as the first. I can only reach an ocean one glass at a time. -------------------------------------------------------------------------------- /Rails Root.md: -------------------------------------------------------------------------------- 1 | # Rails Root 2 | 3 | Rails root is a silly name. It seems to imply that it refers to the location of the installation of Rails on your system--but that's not what the Rails root is. 4 | 5 | The Rails root is the directory of each Rails app. If on your computer you build your app in usr/my_app, then usr/my_app is the Rails root for that particular app. 6 | 7 | When you run a [Rails new command](http://google.com) (`rails new my_app`), you create the Rails root. The directory my_app (the Rails root) is built in whatever directory you're in when you run the Rails new command. -------------------------------------------------------------------------------- /Javascript RegExes.md: -------------------------------------------------------------------------------- 1 | # Javascript Regular Expression Testing 2 | 3 | In Javascript, Regular Expression objects have a `test` method, which allows us to test a string: 4 | 5 | /\d{1, }/.test("Jenny, don't change your number"); 6 | > false 7 | 8 | /\d{1, }/.test("Jenny, don't change your number 867-5309"); 9 | > true 10 | 11 | Regexes have many uses regardless of the language we're using. In Angular, we might use a regex to test whether or not we're at an Admin URL, and to display the appropriate navbar if we are: 12 | 13 | $scope.onAdmin = /\/admin/.test($location.path()); 14 | 15 | -------------------------------------------------------------------------------- /Composition.md: -------------------------------------------------------------------------------- 1 | # Composition 2 | 3 | One of the most basic building blocks of computer programs is composition: 4 | 5 | function cookAndEat(food) { 6 | return eat(cook(food)); 7 | } 8 | 9 | function compose(a, b) { 10 | return function(c) { 11 | return a(b(c)); 12 | } 13 | } 14 | 15 | var cookAndEat = compose(eat, cook); 16 | 17 | If that's all there was to it, composition wouldn't matter much. But like many patterns, using it when it applies is only 20% of the benefit. The other 80% comes from organizing your code such that you can use it: Writing functions that can be composed in various ways. -------------------------------------------------------------------------------- /Computer Networks- Statistical Multiplexing.md: -------------------------------------------------------------------------------- 1 | # Statistical Multiplexing 2 | 3 | In general, multiplexing describes "resource sharing," or our ability to split up resources between users rather than dedicate individual resources to individual users. Office workers often share a printer because not all users will need to use a printer at the same time. How well the shared model works depends on the number of users that might potentially print at a given time, the worst possible probability that any person will be printing at a given moment, and the consequences of multiple people attempting to use a resource at the same time. -------------------------------------------------------------------------------- /Recurrence Relation.md: -------------------------------------------------------------------------------- 1 | # Recurrence Relation 2 | 3 | A recurrence relation is a description of a solution to a problem whose solution depends on smaller instances of the same problem (recurrent problems). 4 | 5 | Consider factorials, where, we can observe that the factorial of a given number _n_ is equivalent to `n * factorial(n-1)`: 6 | 7 | n! = 1 * 2 * 3 * ... n = n * n-1! 8 | 9 | We could describe the solution to a factorial as follows: 10 | 11 | Where T0 is the solution to the 0th factorial: 12 | 13 | T0 = 1 14 | 15 | T1 = 1 16 | 17 | Tn = n * Tn-1 for n > 1 -------------------------------------------------------------------------------- /Naming Migrations.md: -------------------------------------------------------------------------------- 1 | # Migration Naming Convention 2 | 3 | * Migrations should be named following this convention:: 4 | 5 | YYYYMMDDHHMMSS_migration_name.rb # UTC timestamp 6 | 7 | * The latter part of the name (migration_name) should match the name of the [Model class](https://github.com/brettshollenberger/ruby_wiki/blob/master/Writing%20a%20Rails%20Model.md). 8 | 9 | class MigrationName < ActiveRecord::Base 10 | 11 | * If you generate these files using the built-in [Rails migration generator](https://github.com/brettshollenberger/ruby_wiki/blob/master/Writing%20a%20Rails%20Migration.md), it will follow these conventions for you. -------------------------------------------------------------------------------- /Route Globbing.md: -------------------------------------------------------------------------------- 1 | # Route Globbing 2 | 3 | In certain situations, we may want to create routes that allow for greater flexibility than specific positional parameters like: 4 | 5 | /books/:id 6 | 7 | Let's say we want to match: 8 | 9 | /books/author/dickens 10 | 11 | Or 12 | 13 | /books/author/dickens/title/little-dorritt 14 | 15 | Or 16 | 17 | /books/title/little-dorrit/author/dickens 18 | 19 | We can accomplish this via route blobbing: 20 | 21 | get 'books/*specs' => 'books#index' 22 | 23 | Now the Books#index action will have access to a variable number of parameters: 24 | 25 | def index 26 | @books = Books.where(Hash[*params[:specs].split('/')]) 27 | end -------------------------------------------------------------------------------- /Direct versus Indirect Inputs.md: -------------------------------------------------------------------------------- 1 | # Direct versus Indirect Inputs 2 | 3 | In Ruby, any time we send a message to an object other than `self` in order to use its return value, we're using `indirect inputs`. The more indirection that appears in a single method, the more closely that method is tied to the structure of the code around it, and the more likely it is to break. This observation is often referred to as the `Law of Demeter`. 4 | 5 | Input could also come from the surrounding system. For instance, we could use environment variables to influence code within the program: 6 | 7 | def format_time 8 | format = ENV.fetch('TIME_FORMAT') { '%D %r' } 9 | Time.now.strftime(format) 10 | end -------------------------------------------------------------------------------- /Gem Locking.md: -------------------------------------------------------------------------------- 1 | # Gem Locking 2 | 3 | Bundler is a Ruby tool that resolves dependencies between your dependencies--between the external libraries ("gems") that you rely upon in your application. Where this challenge used to be solved by hand, Bundler now solves it for you, and then "locks" the results into a file called the `Gemfile.lock`. The `Gemfile.lock` is the result of the resolution of the gem manifest (the `Gemfile`). 4 | 5 | The `Gemfile.lock` should always be checked into version control, as it ensures the same versions of gems will be used by each developer. Additionally, it ensures that the same gem versions are used in production as the gems that were tested against in development, which helps developers avoid introducing unforeseen bugs. -------------------------------------------------------------------------------- /Fetch vs. Key Lookup.md: -------------------------------------------------------------------------------- 1 | # Fetch vs. Key Lookup 2 | 3 | If you're building data off of data provided by another company or software, you might not know how rigorous they've been with their collection process, so you should make sure you _are_ rigorous in ensuring you don't store garbage data. 4 | 5 | In this case, looking up data on an imported will return `nil` values for keys that don't exist, for instance: 6 | 7 | auth[:user][:first_name] 8 | nil 9 | 10 | Whereas `fetch` will raise a `KeyError`, forcing you to catch the error before you store it: 11 | 12 | auth[:user].fetch(:first_name) 13 | > KeyError 14 | 15 | This will keep us from making assumptions about data we don't have, and causing bugs in seemingly unrelated parts of our code. -------------------------------------------------------------------------------- /Struts.md: -------------------------------------------------------------------------------- 1 | # Struts 2 | 3 | * All URLs are GET 4 | * Querystring encoding 5 | * responseFormat = json param 6 | 7 | * What headers to use? 8 | 9 | * No entity body; query-string 10 | * What status codes are likely to be returned? -> Either success or failure; if they're failure; No error codes are used in header; they're used in response body 11 | 12 | * Most responses contain a status code, session id, and “data” element. Requests to “get” information 13 | will return one/more elements under “data”. When a command fails, the “data” element will be empty, 14 | and an error message will be displayed. 15 | 16 | * No special headers except for session cookie 17 | * Always use POST if we can 18 | * 3 different statuses - success, failure, not logged in -------------------------------------------------------------------------------- /MongoDB Scaling.md: -------------------------------------------------------------------------------- 1 | # Scaling MongoDB 2 | 3 | The easiest way to scale most databases is vertically--increasing the power of their hardware. Vertical scaling is simple, reliable, and to a point, cost-effective. But what happens when you can't scale vertically any longer and you still need greater computing power? You begin scaling horizontally (or maybe you've been doing this the whole time) -- you can begin to distribute the database across multiple machines. Horizontal scaling mitigates the consequences of failure and reduces costs, since cheaper hardware can be used. 4 | 5 | MongoDB manages horizontal scaling for you via auto-sharding, a process that manages the distribution across nodes. MongoDB handles the addition of shard nodes as well as automatic failover. -------------------------------------------------------------------------------- /Gems.md: -------------------------------------------------------------------------------- 1 | # Gems 2 | 3 | Gems are Ruby's implementation of libraries--reusable chunks of code. 4 | 5 | As you build programs, you'll find yourself reusing certain bits of functionality. Often, these can become gems. 6 | 7 | Other developers can then download your gems via RubyGems, using the RubyGems' [Command Line Interface](http://www.google.com). Here's an example command, which downloads and installs the gem Rails. 8 | 9 | gem install rails 10 | 11 | Simple, no? The RubyGems CLI queries [RubyGems.org](rubygems.org) for a gem matching the name "rails." In this case, it will find the Rails framework and download it. For obvious reasons, your gem cannot share the name of another gem. 12 | 13 | Look here for more [RubyGem CLI commands](http://www.google.com). -------------------------------------------------------------------------------- /Chameleon.md: -------------------------------------------------------------------------------- 1 | # Chameleon 2 | 3 | ## Goals: 4 | 5 | Modularization as "number one theme." 6 | 7 | 1) Centralize & modularize Javascript modules & CSS 8 | 9 | * Bower for front-end modules 10 | * `npm` for back-end modules 11 | * `edmodo-bootstrap`: Common assets (LESS files & custom Javascript modules) 12 | 13 | 2) Rendr (thin Node.js layer) - Run Backbone apps on the server 14 | 15 | 3) How it interacts with OneAPI 16 | 17 | ## My entry point: 18 | 19 | April 9th 20 | 21 | District & school profiles - Desktop, tablet, and mobile experiences & creating a good user experience 22 | 23 | ## Style Guide 24 | 25 | Features different components; can visualize different pieces; learn Bootstrap 3 inside and out 26 | 27 | ## API Design 28 | 29 | Adam Stepinsky 30 | 31 | -------------------------------------------------------------------------------- /Concatenating Regular Expressions in Javascript.md: -------------------------------------------------------------------------------- 1 | # Concatenating Regular Expressions in Javascript 2 | 3 | Suppose we have a number of regular expressions defined by the user that we want to combine at runtime to find any matches: 4 | 5 | new RegExp([ 6 | (regexSources.regexOne).source, 7 | (regexSources.regexTwo).source 8 | ].join('|'), 'g'); 9 | 10 | The `source` property of regular expressions allows us to grab their text, without flags. We can pass in text to the RegExp constructor (rather than a regular expression, which will become wrapped in another set of backslashes, breaking our formatting). 11 | 12 | We join each of the statements in the expression with the pipe (`|`), allowing each to match. 13 | 14 | Finally, we can pass flags at the end of our expression. -------------------------------------------------------------------------------- /Common Backbone Errors.md: -------------------------------------------------------------------------------- 1 | # Common Backbone Errors 2 | 3 | | You see | Real Problem | 4 | | -------------- | :----------------------------------------------------------------------------------------: | 5 | | Duplicated models when you visit a page for a second time (not on initial page load) | Your model's idAttribute is not set, or is wrong. It should be the ID used in the database. | 6 | | Browser console error: "Can't find module 'app/collection/' or 'app/model/' | You haven't set the id attribute of the model or collection. | 7 | -------------------------------------------------------------------------------- /type, which, and whereis.md: -------------------------------------------------------------------------------- 1 | # type, which, and whereis 2 | 3 | `type` is a bash built-in that searches your environment (files in $PATH, keywords, aliases, built-ins, and functions) for executable commands that you pass to it as arguments. 4 | 5 | $ type which 6 | which is a shell builtin 7 | 8 | `which` is very similar, and widely used, but it only searches the files in $PATH and provides slightly different output: 9 | 10 | $ which which 11 | which: shell built-in command 12 | 13 | #### Yes, but where are the files? 14 | 15 | To find the location of executables with these commands, you can also pass the `-a` flag to either of them: 16 | 17 | $ type -a which 18 | which is a shell builtin 19 | which is /usr/bin/which 20 | which is /usr/bin/which 21 | 22 | Or use the builtin `whereis`: 23 | 24 | $ whereis heroku 25 | /usr/bin/heroku -------------------------------------------------------------------------------- /Javascript Inheritance.md: -------------------------------------------------------------------------------- 1 | # Javascript Inheritance 2 | 3 | 4 | 5 | function Parent(name) { 6 | this.name = name; 7 | } 8 | 9 | Parent.prototype.say = function() { return this.name; } 10 | 11 | function Child() {}; 12 | 13 | function inherit(C, P) { 14 | C.prototype = new P(); 15 | } 16 | 17 | var bert = new Child('bert'); 18 | 19 | bert.say(); 20 | >> 'bert' 21 | 22 | Drawbacks: most of the time you don't want the own properties because they're specific to an instance. 23 | 24 | #### Rent-A-Constructor // Supering 25 | 26 | function Article(title) { 27 | this.title = title; 28 | } 29 | 30 | function Blog(title, author) { 31 | Article.call(this, title); 32 | this.author = author; 33 | } 34 | 35 | var bloge = new Blog(); 36 | 37 | bloge._constructor 38 | >> [function: Blog] 39 | 40 | function Bloge() { 41 | 42 | -------------------------------------------------------------------------------- /Array Style.md: -------------------------------------------------------------------------------- 1 | #Arrays 2 | 3 | ####Prefer literal arrays & hash creation, unless you need to pass parameters to their constructors. 4 | 5 | # no bueno 6 | hash = Hash.new 7 | arr = Array.new 8 | 9 | # bueno 10 | hash = {} 11 | arr = [] 12 | 13 | #### Prefer %w syntax to literal array syntax when you need an array of words. 14 | 15 | #ick 16 | STATES = ['draft', 'open', 'closed'] 17 | 18 | #yum 19 | STATES = %w(draft, open, closed) 20 | 21 | #### Prefer %i to literal array syntax when you need an array of symbols. 22 | 23 | #no-no 24 | ice_cream = [:vanilla, :chocolate, :rocky_road] 25 | 26 | #yes-yes 27 | ice_cream = %i(vanilla, chocolate, rocky-road) 28 | 29 | #### Avoid creating large gaps in arrays 30 | 31 | # no good 32 | arr = [] 33 | arr[100] = 1 34 | 35 | # Now you've got a mess of nils 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /Javascript Metaprogramming.md: -------------------------------------------------------------------------------- 1 | # Javascript Metaprogramming 2 | 3 | Object.prototype.defineMethod = function(methodName, methodBody) { 4 | Object.defineProperty(this, methodName, { 5 | enumerable: true, 6 | configurable: true, 7 | value: methodBody 8 | }); 9 | } 10 | 11 | 12 | Object.prototype.aliasMethodChain = function(methodName, featureName) { 13 | this.defineMethod(methodName + "Without" + featureName.capitalize(), this[methodName]); 14 | this.defineMethod(methodName, this[methodName + "With" + featureName.capitalize()]); 15 | } 16 | 17 | function Doge() { 18 | this.defineMethod("bark", function() { 19 | return "woof!"; 20 | }); 21 | 22 | this.defineMethod("barkWithLogging", function() { 23 | console.log("Bark called!"); 24 | return this.barkWithoutLogging(); 25 | }); 26 | 27 | this.aliasMethodChain("bark", "logging"); 28 | } -------------------------------------------------------------------------------- /REST Constraint - Client-Server Separation.md: -------------------------------------------------------------------------------- 1 | # REST Constraint: Client-Server Separation 2 | 3 | Client-server separation is one of the foundational constraints in RESTful networking architecture. 4 | 5 | The server provides services upon request. Usually the server is a non-terminating process that provides these services to many clients. 6 | 7 | The client is a triggering mechanism that allows a user to request services. The client sends the request to the server, and the server replies with either a refusal to complete the request or the results of the request. 8 | 9 | The primary reason for client-server separation is separation of concerns. This separation allows the server to remain focused and scalable, and usually moves the entire user interface to the client. Separation also allows the client and server to evolve independently, provided the server's interface does not change. -------------------------------------------------------------------------------- /Rack.md: -------------------------------------------------------------------------------- 1 | # Rack 2 | 3 | Rack is a modular interface for handling web requests, written in Ruby, with support for many different web servers. 4 | 5 | It abstracts the handling of HTTP requests to a single, simple, call method. 6 | 7 | Rack can be used by anything from a plain Ruby script to a Rails application. 8 | 9 | class HelloWorld 10 | def call(env) 11 | [200, {"Content-Type" => "text/plain"}, ["Hello world!"]] 12 | end 13 | end 14 | 15 | Rack::Handler::Thin.run HelloWorld.new, :Port => 8080 16 | 17 | Incoming HTTP requests invoke the call method, and pass a hash of environment variables. 18 | 19 | The call method should return a 3-element array consisting of the status, a hash of response headers, and the body of the request. 20 | 21 | In a Rails application, we have a Rake task to see which Rack middlewares are in use: 22 | 23 | rake middleware 24 | 25 | -------------------------------------------------------------------------------- /Ruby Hook Methods.md: -------------------------------------------------------------------------------- 1 | # Ruby Hook Methods 2 | 3 | When we `include` or `extend` modules, we gain access to hook methods that let us tap into the including or extending class: 4 | 5 | module Validatable 6 | def self.extended(klass) 7 | klass.class_eval do 8 | def self.validates(name, &validation) 9 | define_method "#{name}=" do |value| 10 | raise "Invalid attribute" unless validation.call(value) 11 | instance_variable_set("@#{name}", value) 12 | end 13 | 14 | define_method name do 15 | instance_variable_get("@#{name}") 16 | end 17 | end 18 | end 19 | end 20 | end 21 | 22 | class Person 23 | extend Validatable 24 | 25 | validates :age do |age| 26 | age >= 21 27 | end 28 | end 29 | 30 | person = Person.new 31 | 32 | person.age = 18 33 | >> RuntimeError: Invalid attribute 34 | 35 | person.age = 21 36 | 21 37 | -------------------------------------------------------------------------------- /Annotate Models.md: -------------------------------------------------------------------------------- 1 | # Annotate Models 2 | 3 | The annotate gem creates comments in your model classes to remind you of the structure of that part of your schema. For example: 4 | 5 | user.rb 6 | # == Schema Information 7 | # 8 | # Table name: users 9 | # 10 | # id :integer not null, primary key 11 | # name :string(255) 12 | # email :string(255) 13 | # created_at :datetime not null 14 | # updated_at :datetime not null 15 | # password :string(255) 16 | # 17 | class User < ActiveRecord::Base 18 | attr_accessible :email, :name, :password 19 | end 20 | 21 | To create these annotations: 22 | 23 | 1) In your Gemfile: 24 | 25 | group :development do 26 | gem 'annotate' 27 | end 28 | 29 | 2) In Terminal: 30 | 31 | bundle exec annotate --position before 32 | 33 | 3) Run annotate any time your model changes to keep the annotations up-to-date -------------------------------------------------------------------------------- /REST Constraint- Statelessness.md: -------------------------------------------------------------------------------- 1 | # REST Constraint: Statelessness 2 | 3 | One of the constraints of RESTful architecture is statelessness. HTTP is necessarily stateless, which means that each request to the server must contain all necessary information for completing the request. 4 | 5 | This improves visibility on the server: the server need not look beyond a single request to understand how to fulfill it. 6 | 7 | This improves reliability on the server: it eases the task of recovering from partial failures. 8 | 9 | This improves scalability on the server: since the server need not manage application state, or resources across requests, it can quickly free resources and scale to manage many requests. 10 | 11 | Statelessness also reflects a trade-off in architecture: since the server cannot manage application state or resources across requests, each client must properly implement application semantics in order to succeed. -------------------------------------------------------------------------------- /Serializing Rails Attributes.md: -------------------------------------------------------------------------------- 1 | # Serializing Rails Attributes 2 | 3 | ActiveRecord text columns have the ability to serialize data as YAML (Yet Another Markup Language), Rails' default serialization format. To do so, let's add a column to our user model: 4 | 5 | def change 6 | add_column :users, :preferences, :text 7 | end 8 | 9 | And in our model, we'll tell ActiveRecord to serialize the object: 10 | 11 | class User < ActiveRecord::Base 12 | serialize :preferences, Hash 13 | end 14 | 15 | Additionally, we can set a default for our accessor, since this object will be `nil` by default: 16 | 17 | class User < ActiveRecord::Base 18 | def preferences 19 | self[:preferences] || self[:preferences] = {} 20 | end 21 | end 22 | 23 | ## ActiveRecord::Store 24 | 25 | Alternately, you can perform all of this at once with the use of the `store` method: 26 | 27 | class User < ActiveRecord::Base 28 | store :preferences 29 | end -------------------------------------------------------------------------------- /Sublime Snippets.md: -------------------------------------------------------------------------------- 1 | # Creating Sublime Snippets 2 | 3 | 4 | 6 | 7 | 8 | 9 | Angular Demo - $0 10 | 11 | 12 | 13 |

$0

14 |
15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | ]]>
23 | 24 | angular 25 | 26 | 27 |
28 | -------------------------------------------------------------------------------- /Computer Networks- The Physical Layer - Media.md: -------------------------------------------------------------------------------- 1 | # Physical Layer: Types of Media 2 | 3 | Media propagates signals that carry bits of information. 4 | 5 | ## Wires - Twisted Pair 6 | 7 | Very common; used in LANs and telephone lines. Twists reduce radiated signal. 8 | 9 | ## Wires - Coaxial Cable 10 | 11 | Also common. Better shielding for better performance. Can carry more data faster across longer distance. 12 | 13 | ## Fiber 14 | 15 | Long, thin, pure strands of glass. Enormous bandwidth (high speed) over long distances. 16 | 17 | ## Wireless 18 | 19 | Sender radiates signal over a region. It can reach potentially many receivers. Nearby signals with the same frequency however will interfere at a receiver; need to coordinate use. 20 | 21 | We must be careful to allocate WiFi to a small portion of the radio spectrum. 22 | 23 | The portion of the spectrum used for WiFi have an interesting story. The frequencies we like for data communication tend to be in the microwave band (WiFi and 3G). -------------------------------------------------------------------------------- /MongoDB Replica Sets.md: -------------------------------------------------------------------------------- 1 | # MongoDB Replica Sets 2 | 3 | MongoDB replica sets are much like the classic master/slave relationship in relational databases. 4 | 5 | * They're used to maximize reliability of database resources by replicating the primary database to one or more secondary databases whenever a write is performed (which can only be performed to the primary database). 6 | * They allow horizontal scaling for high read/low write & update environments. A load balancer can be used to route requests to appropriate slaves to improve read performance as an application scales. 7 | * One unique quality: Mongo replica sets automate failover. When the primary database fails, the cluster will automatically promote a secondary resource to primary. When the old primary comes back online, it will do so as a secondary resource. Automated failover is still potentially contentious because it's hard to get right, and there are parts of the application stack that DevOps teams will be hesitant to automate (failover being a big one). -------------------------------------------------------------------------------- /Continuation-Passing Style.md: -------------------------------------------------------------------------------- 1 | # Continuation Passing Style 2 | 3 | Continuation passing style is an approach to programming single-threaded systems in a non-blocking manner. In CPS, functions do not return their results to their caller--in fact they don't return to their caller ever. Instead, their caller registers a callback, which is passed the "return value": 4 | 5 | Blocking: 6 | function id(x) { 7 | return x; 8 | } 9 | 10 | Continuation-passing style: 11 | function id(x, cb) { 12 | cbv(x); 13 | } 14 | 15 | CPS Factorial: 16 | function factorial(n, then) { 17 | if (n === 0) { 18 | then(1); 19 | } else { 20 | factorial(n-1, function(result) { 21 | then(n*result); 22 | }); 23 | } 24 | } 25 | 26 | CPS Tail Factorial: 27 | function tail_factorial(n, r, then) { 28 | if (n === 0) { 29 | then(r); 30 | } else { 31 | factorial(n-1, n*r, then); 32 | } 33 | } 34 | 35 | function factorial(n, then) { 36 | return tail_factorial(n, 1, then); 37 | } 38 | 39 | 40 | -------------------------------------------------------------------------------- /MongoDB Capped Collections.md: -------------------------------------------------------------------------------- 1 | # Capped Collections in MongoDB 2 | 3 | Mongo implements capped collections for high-performance logging, ensuring fast reads and writes at the expense of ephemeral data. In situations like logging, persisted data may not be desirable, and capped collections prevent you from having to prune the collection manually to include only recent data; once a capped collection reaches its maximum size, new inserts will overwrite the least-recently-inserted documents for you. 4 | 5 | By default, capped collections don't feature an index on the `_id` field be design. No indexing means faster write times, and capped collections are made with performance in mind. No indexing also means sequential processing in either natural order (order of insertion) or reverse-natural order: 6 | 7 | db.log.actions.find().sort({$natural: -1}); 8 | 9 | When creating capped collections, you have to specify that the collection is capped, as well as its size: 10 | 11 | db.createCollection(name, {capped: true, size: 1024}); -------------------------------------------------------------------------------- /Rails Env.md: -------------------------------------------------------------------------------- 1 | # Rails Env 2 | 3 | Rails applications are preconfigured with 3 standard environments, which can be used to specify a large number of environment-specific variables that need to change between the test, development, and production environments. We often find ourselves changing configuration between these environments for things like mail clients, file uploads, eager loading, and any number of other specifics. 4 | 5 | Way back in Rails 2, the variable declaring the current environment was specified using the environment variable `ENV["RAILS_ENV"]` . Since Rails 3, this same variable now hangs off of the `Rails` object itself, using `Rails.env`. 6 | 7 | The new `Rails.env` variable inherits from `ActiveSupport::StringInquirer`, which allows it to respond to any arbitrary methods inquiring into its value, e.g.: 8 | 9 | Rails.env.production? 10 | > true 11 | 12 | Rails.env.whatever? 13 | > false 14 | 15 | The inquiry syntax will work with any prefix, and will only return true if the value of `Rails.env` matches it exactly. -------------------------------------------------------------------------------- /Event-Driven Javascript.md: -------------------------------------------------------------------------------- 1 | # Javascript Events 2 | 3 | Javascript is a single-threaded language, meaning only a single process can be handled at a time. If a long-running process were to tie up the thread, it would spell disaster (and slow code). 4 | 5 | To handle this issue, Javascript relies on event-driven callbacks--functions that are registered to be called when an asynchronous process completes. 6 | 7 | The most important point here is that Javascript event handlers do not run until the thread is free. Even if an asynchronous event should fire immediately, it will not actually fire until the rest of the code has finished processing, and the thread is ready: 8 | 9 | var functionHasReturned = false; 10 | 11 | setTimeout(function() { 12 | console.assert(functionHasReturned); 13 | }, 0); 14 | 15 | var functionHasReturned = true; 16 | 17 | The code above will never fail. Though the callback fires after 0 milliseconds, Javascript will not enter the event loop, and call the callback until after it has processed functionHasReturned = true. -------------------------------------------------------------------------------- /Computer Networks- The Physical Layer- Types of Media.md: -------------------------------------------------------------------------------- 1 | # The Physical Layer: Types of Media 2 | 3 | # Physical Layer: Types of Media 4 | 5 | Media propogates signals that carry bits of information. 6 | 7 | ## Wires - Twisted Pair 8 | 9 | Very common; used in LANs and telephone lines. Twists reduce radiated signal. 10 | 11 | ## Wires - Coaxial Cable 12 | 13 | Also common. Better shielding for better performance. Can carry more data faster across longer distance. 14 | 15 | ## Fiber 16 | 17 | Long, thin, pure strands of glass. Enormous bandwidth (high speed) over long distances. 18 | 19 | ## Wireless 20 | 21 | Sender radiates signal over a region. It can reach potentially many receivers. Nearby signals with the same frequency however will interfere at a receiver; need to coordinate use. 22 | 23 | We must be careful to allocate WiFi to a small portion of the radio spectrum. 24 | 25 | The portion of the spectrum used for WiFi have an interesting story. The frequencies we like for data communication tend to be in the microwave band (WiFi and 3G). -------------------------------------------------------------------------------- /RSpec.md: -------------------------------------------------------------------------------- 1 | # Rspec 2 | 3 | #### Workflow 4 | 5 | * Generate the integration test. This generates the static_pages_spec.rb in the spec/requests directory. 6 | 7 | rails generate integration_test static_pages 8 | 9 | * Write the test: 10 | 11 | require 'spec_helper' 12 | describe "Static pages" do 13 | describe "Home page" do 14 | it "should have the content 'Sample App'" do 15 | visit '/static_pages/home' 16 | expect(page).to have_content('Sample App') 17 | end 18 | ... 19 | 20 | We specify the page we're describing (Home page), and in the "it" statement write whatever we want to describe the test. RSpec doesn't care what we call it--like any other function or method. 21 | 22 | The body of the spec describes the actions to take: visit the homepage at the specified URL. If it has the content "Sample App," it passes the test. 23 | 24 | bundle exec spec spec/requests/static_pages_spec.rb 25 | 26 | ``bundle exec`` ensures that RSpec runs in the environment specified by the Gemfile. Then pass the path to the spec file. 27 | 28 | 29 | -------------------------------------------------------------------------------- /Ruby Regexes.md: -------------------------------------------------------------------------------- 1 | # Ruby Regexes 2 | 3 | Regular Expressions are patterns often used to ensure user input matches specific criteria (e.g. to ensure a user has entered a valid email address). 4 | 5 | #### Patterns in Ruby are specified using _/pattern/_ 6 | 7 | /Perl|Python/ # Perl or Python 8 | 9 | /\d\d:\d\d:\d\d/ # A time, such as 12:35:56 10 | 11 | #### Ruby uses the =~ match operator to match strings against regexes 12 | 13 | email = "stupidAOLacct590@aol.com" 14 | 15 | email =~ /\d{3}/ # If matches, returns the start position of the match 16 | > 13 17 | 18 | email =~ /\d{4}/ # If no match, returns nil 19 | > nil 20 | 21 | #### Since nil is returned for no match, regexes can be used in conditional piping: 22 | 23 | email = "brett.shollenberger@gmail.com" 24 | 25 | if email =~ /\b[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-z]{2,4}\b/ 26 | puts "Logged in." 27 | end 28 | 29 | Check out the [Regex Cheat Sheet](https://github.com/brettshollenberger/ruby_wiki/blob/master/Regex%20Cheat%20Sheet.md) for more info on regular expressions. -------------------------------------------------------------------------------- /Database Sandboxing.md: -------------------------------------------------------------------------------- 1 | # Database Sandboxing 2 | 3 | When learning [Active Record](https://github.com/brettshollenberger/ruby_wiki/blob/master/Active%20Record.md), it can be useful to play around in the [Rails console](google.com) without actually affecting your database. Since the Rails console automatically loads the [Rails environment](google.com), which includes the [models](https://github.com/brettshollenberger/ruby_wiki/blob/master/Writing%20a%20Rails%20Model.md) and database you're using, you'll be able to affect your database using [Active Record methods](google.com) unless you create a sandbox. 4 | 5 | To do this, you can run: 6 | 7 | rails console --sandbox 8 | 9 | As you tinker with your models, you'll see your SQL INSERTS and DELETES and UPDATES prefaced by SAVEPOINT lines, indicating that the database will be rolled back on quit. 10 | 11 | 1.9.3-p392 :001 > Event.create(location: "Back Bay") 12 | (0.2ms) SAVEPOINT active_record_1 13 | 14 | Which Rails will remind you of on exit. 15 | 16 | 1.9.3-p392 :002 > exit 17 | (0.6ms) ROLLBACK 18 | 19 | -------------------------------------------------------------------------------- /Automate Tests with Guard.md: -------------------------------------------------------------------------------- 1 | # Automate Tests with Guard 2 | 3 | Guard is a command line tool that watches a file structure and automates events when changes are made in those files. While Guard has many uses, this article explores how we can use RSpec and Guard together to automate tests. 4 | 5 | #### Installing Guard 6 | 7 | Once you have [RSpec setup](https://github.com/brettshollenberger/ruby_wiki/blob/master/Setting%20Up%20RSpec.md) in your Rails project, you're ready to add Guard. 8 | 9 | 1) Add guard-rspec to the Gemfile 10 | 11 | group :development, :test do 12 | gem 'rspec-rails' # These are set up from installing RSpec and Capybara 13 | gem 'capybara' 14 | gem 'guard-rspec' 15 | end 16 | 17 | 2) Add other :test group gems 18 | 19 | group :test do 20 | gem 'rb-fsevent' 21 | gem 'growl' 22 | end 23 | 24 | 3) `bundle` 25 | 26 | 4) `bundle exec guard init spec` 27 | 28 | 5) Edit the Guardfile to add: 29 | 30 | require 'active_support/core_ext' 31 | 32 | guard 'spec, :all_after_pass => false do 33 | 34 | 6) To run: 35 | 36 | bundle exec guard -------------------------------------------------------------------------------- /Seed.md: -------------------------------------------------------------------------------- 1 | # seed.rb 2 | 3 | Movie.create([ 4 | {name: 'Batman?', description: 'The Dark Knight Rises?'}, 5 | {name: 'Man of Steel', description: 'A boring 90 minutes'}, 6 | ]) 7 | 8 | menu_items_spec.rb 9 | 10 | require 'spec_helper' 11 | 12 | describe Seeder do 13 | let(:seeder) { Seeders::MenuItems } 14 | 15 | it "seeds the database" do 16 | menu_item_count = MenuItem.count 17 | seeder.seed 18 | expect(MenuItem.count).to_not eq(menu_item_count) 19 | end 20 | end 21 | 22 | lib/seeders/menu_items.rb 23 | 24 | module Seeders 25 | module MenuItems 26 | class << self 27 | def seed 28 | MenuItem.destroy_all 29 | menu_items.each do |name, array| 30 | item = MenuItem.new 31 | item.name = name 32 | item.category = array.shift 33 | item.price_in_cents = 1000 34 | item.description = "Yummy" 35 | item.save 36 | end 37 | end 38 | 39 | def menu_items { 40 | "Bonnie's Crab Cakes" => ['Seafood', 'lump crabmeat', 'breadcrumbs', 'seasoning'], 41 | "Item 2..." 42 | } 43 | end 44 | end 45 | end 46 | end 47 | -------------------------------------------------------------------------------- /Scoping Routes.md: -------------------------------------------------------------------------------- 1 | # Scoping Routes 2 | 3 | Rails provides a variety of ways to bundle together related routing rules: 4 | 5 | ## Controller 6 | 7 | scope :controller => :books do 8 | get "books" => :index, as: :books 9 | get "book/:id" => :show, as: :book 10 | end 11 | 12 | controller :books do 13 | get "books" => "index", as: :books 14 | end 15 | 16 | ## Path 17 | 18 | scope :path => "/books" do 19 | get "/" => :index, as: :books 20 | get "/:id" => :show, as: :book 21 | end 22 | 23 | ## Name Prefix 24 | 25 | scope :auctions, as: "admin" do 26 | get "new" => :new, as: :new_auction 27 | end 28 | 29 | >> admin_new_auction_path 30 | 31 | ## Namespace 32 | 33 | Sets up a module, name prefix, and path prefix in one declaration: 34 | 35 | namespace :api do 36 | namespace :v1 do 37 | controller: :books do 38 | get "books" => :index, as: :books 39 | get "book/:id" => :show, as: :book 40 | end 41 | end 42 | end 43 | 44 | >> api_v1_books_path(:json) 45 | >> /api/v1/books.json 46 | 47 | >> api_v1_book_path(@book, :json) 48 | >> /api/v1/books/little-dorrit.json 49 | 50 | -------------------------------------------------------------------------------- /Database Indices.md: -------------------------------------------------------------------------------- 1 | # Database Indices 2 | 3 | Database indices work like book indices: Without them, you'd have to flip through every page to find occurrences of particular topics. 4 | 5 | In both cases, indices are only useful if they make it easier to find useful information. You wouldn't have a book indexed with every word in the book, because no one needs to find every occurrence of the definitives and conjunctions. For the same reason, it's important to ask yourself how you'll need to access information on a given table. Will you need to look up users by email? Username? Both? 6 | 7 | Answering this question up front will keep your table efficient later. Without the right database indices, you'll end up asking the database to perform a _full-table scan_ each time you use a method like find_by_email. 8 | 9 | If you do need to retroactively add an index to a table column, you can: 10 | 11 | 1) In Terminal 12 | 13 | rails g migration add_index_to_users_email 14 | 15 | 2) Write the migration: 16 | 17 | def change 18 | add_index :users, :email, unique: true 19 | end 20 | 21 | 3) Of course: 22 | 23 | rake db:migrate -------------------------------------------------------------------------------- /Indexing AJAX Applications.md: -------------------------------------------------------------------------------- 1 | # Indexing AJAX Applications 2 | 3 | Pages that generate content and metadata asynchronously cannot be crawled by Facebook or Google, making all your SEO people's hard work for naught. Their crawlers index your page without executing any Javascript, meaning that they'll see your templating engine's inner workings instead of your content. 4 | 5 | To solve this problem, you have to indicate that your site supports the AJAX crawling scheme by adding a hashbang to your URLs, e.g.: 6 | 7 | mygreatsite.com/#!/coolpage 8 | 9 | The hashbang indicates the the web bots of the world that your site is AJAX crawlable, and the bots will respond by making a request to your application using the `_escaped_fragment_` syntax. 10 | 11 | mygreatsite.com/?_escaped_fragment_=coolpage 12 | 13 | It's important to note that you'll need to URL unescape any pages you send to the bots, so the URL you send ends up looking like: 14 | 15 | mygreatsite.com%2F%23%21%2Fcoolpage 16 | 17 | When your server sees the escaped fragment syntax, its job is to respond with an HTML snapshot of the content instead of the normal page. -------------------------------------------------------------------------------- /Postgres.md: -------------------------------------------------------------------------------- 1 | #Postgres 2 | 3 | #### Installation: 4 | * Follow the instructions on the [Heroku help page](https://devcenter.heroku.com/articles/heroku-postgresql#local-setup) 5 | * For Mac: [Download Postgres.app](http://postgresapp.com). 6 | * [Documentation](http://postgresapp.com/documentation) is obviously helpful, but here are the important steps: 7 | 1) Add the Postgres bin to your path (e.g. via the .profile, .bashrc, .zshrc, or whatever you use to make sure it gets set for every Terminal session). Ensures you get to use the binaries that ship with Postgres like ``pg_dump`` and ``pg_restore`` 8 | 9 | ### For Postgres 10 | export PATH="/Applications/Postgres.app/Contents/MacOS/bin:$PATH" 11 | 2) Start a new Terminal session to ensure the path is setup correctly: 12 | 13 | which psql 14 | 15 | Which should return the path you just set up; any other bin is incorrect. 16 | 17 | 3) Run the Postgres app 18 | 4) Now you can run Postgres; if you haven't added the Postgres bin to your path, you have to specify a host with the -h or --host flags. 19 | 20 | psql 21 | psql -h localhost # You haven't added the bin 22 | -------------------------------------------------------------------------------- /Unix Processes.md: -------------------------------------------------------------------------------- 1 | # Unix Processes 2 | 3 | Unix processes are programs that are run in-memory. Each process has a unique process identifier (PID) to identify it. 4 | 5 | # list all currently running processes in long-format 6 | $ ps -l 7 | 8 | Processes (parent processes) like shells, which are just programs designed to run other programs, can spawn other processes (child processes). Child processes inherit their parent's context--all of the environment variables set, the current directory, etc. But child processes are also free to live a life of their own without directly altering the parent process (if run as shell scripts). Child processes can alter environment variables like `$PATH`, or `cd` all over the file system without fear of altering the variables in their parent process, or changing the parent's current directory. When the process exits, the parent process (usually the shell) will continue in the same directory, with unaltered variables. 9 | 10 | Shell functions on the other hand tend to operate in the same process. A notable exception is in `for` loops that redirect `STDOUT` to another process, which will spawn a child process. -------------------------------------------------------------------------------- /Symlink.md: -------------------------------------------------------------------------------- 1 | Symbolic Links (symlinks) 2 | ======================== 3 | 4 | Symlinks are like nicknames for files or directories you want to reference. They're like telling your computer, "When I say 'John,' what I mean is 'John Jacob Jingleheimer Schimdt.'" 5 | 6 | For the more technically minded, a symlink is the equivalent of an alias (Mac) or a shortcut (Windows) that you type at your command line. Instead of creating a copy of the file, the symlink, which is a shorter, easier to remember name, points to the full path of the file or directory itself. 7 | 8 | ``` 9 | #> ln -s 10 | ``` 11 | 12 | Creates a symbolic link (ln stands for hard link; the -s flag stands for symbolic). The symbolic link then takes two arguments: the full path to reference, and the shorter name you want to use. 13 | 14 | ``` 15 | #> ln -s "/Applications/Sublime Text 2.app/Contents/SharedSupport/bin/subl" ~/bin/subl 16 | ``` 17 | 18 | Creates a link to /Applications/Sublime Text 2.app/Contents/SharedSupport/bin/subl via the shorter bin/subl. 19 | 20 | Now you can type 21 | ``` 22 | #> bin/subl filename 23 | ``` 24 | 25 | To open the corresponding file in Sublime Text 2. 26 | -------------------------------------------------------------------------------- /Best Practices for Backbone Templating.md: -------------------------------------------------------------------------------- 1 | # Best Practices for Backbone Templating 2 | 3 | 1) Don't set the `el` on the view. Allow the view to instantiate its own `el`: 4 | 5 | // Wrong 6 | Backbone.View.extend({ 7 | el: '#container' 8 | }); 9 | 10 | // Right: 11 | Backbone.View.extend({}); 12 | 13 | When you set the `el` explicitly, each new rendering will be given the same `el`, and will overwrite the previous instance: 14 | 15 | // View 16 | render: function() { 17 | var html = "

<%= book.title %> by <%= book.author %>

"; 18 | var template = _.template(html); 19 | var rendered = template({book: this.model.attributes}); 20 | 21 | $(this.el).html(rendered); 22 | 23 | return this; 24 | } 25 | 26 | // Controller, Route, etc. 27 | _.each(models, function(model) { 28 | var view = new UserView({model: model}).render(); 29 | }); 30 | 31 | Results in just one view being rendered. 32 | 33 | Instead: 34 | 35 | // View 36 | Same as above 37 | 38 | // Controller, Route, etc. 39 | _.each(models, function(model) { 40 | var view = new UserModel({model: model}); 41 | $('#container').append(view.render().el); 42 | }); -------------------------------------------------------------------------------- /Named Routes.md: -------------------------------------------------------------------------------- 1 | # Named Routes 2 | 3 | Named routes help us to define RESTful routes, and make it easy for us as programmers to create links. 4 | 5 | When we name a route, a new method gets defined: 6 | 7 | get 'books/:id' => 'books#show', as: 'book' 8 | 9 | app.book_path(1) 10 | >> '/books/1' 11 | 12 | ## Syntactic Sugar 13 | 14 | We can and should also pass in objects to our helper to create the path: 15 | 16 | <%= link_to @book.title, book_path(@book) %> 17 | 18 | This will call `to_param` on the item we pass in, and pass off the object's `id`. 19 | 20 | If we want to instead use a title in our route, we can override the the `to_param` method in our Book model: 21 | 22 | # book.rb 23 | 24 | def to_param 25 | title.parameterize 26 | end 27 | 28 | @book.to_param 29 | // "little-dorrit" 30 | 31 | Of course, now we must make precautions to dig out the Book again. We could find it using `titleize`, perhaps: 32 | 33 | def show 34 | @book = Book.where(title: params[:title].titleize).first 35 | end 36 | 37 | Or if it's really munged, we could add a new field: 38 | 39 | def show 40 | @book = Book.where(munged_title: params[:title]) 41 | end -------------------------------------------------------------------------------- /Unix Command Substitution.md: -------------------------------------------------------------------------------- 1 | # Unix Command Substitution 2 | 3 | The `STDOUT` of a Unix command can be substituted as the `STDIN` to another program by surrounding the command in backticks. 4 | 5 | $ ls `echo $PATH | tr ':' ' '` 6 | 7 | The `STDOUT` from the command above is a whitespace-separated list of directories in the user's `$PATH`, the perfect input to the `ls` program, which lists the contents of each in `STDOUT`. 8 | 9 | Unix command substitution can be mighty powerful in combination with other commands: 10 | 11 | for dir in `echo $PATH | tr ':' ' '`; do 12 | cd ${dir} 13 | 14 | for file in `ls *`; do 15 | if [ -x ${file} -a ! -d ${file} ] 16 | echo ${file} 17 | fi 18 | done 19 | done | sort 20 | 21 | The `for` loop in the example above loops through each directory in the user's `$PATH`, `cd`s into the directory, and `echo`s the name of the file if the file is executable (`-x`) and (`-a`) it is not (`!`) a directory (`-d`). The program pipes (`|`) the output to the `sort` program, and the final result is a sorted list of executable programs in the user's `$PATH`, the list of directories Unix will search when a user attempts to run a program. -------------------------------------------------------------------------------- /Conditionally Apply Classes with ng-class.md: -------------------------------------------------------------------------------- 1 | # Conditionally Apply Classes with ng-class 2 | 3 | `ng-class` allows you to set CSS on a particular HTML element dynamically by data binding an expression that represents all classes to be added: 4 | 5 |
6 | 7 | The Angular docs on this one kind of suck, but you can use conditional syntax like Ruby's shorthand statement modifiers: 8 | 9 | applyClass if true # An if statement modifying whether or not to apply the class, as in plain English 10 | 11 | applyClass unless true # And an unless statement doing the same 12 | 13 | Angular allows us to use the `:` operator to perform the equivalent of an `if` modifier: 14 | 15 |
16 | 17 | `ng-repeat` tells us which collection to iterate over, and `$index` is a built-in referring to the number of the current iteration. In my markup, I'll need to put every third project on a new line so they format correctly. Using the modulus operator, we can determine whether or not the number of the current iteration is divisible by three, and apply the classic clearfix (`clear: both;`) if it is. -------------------------------------------------------------------------------- /Yeoman.md: -------------------------------------------------------------------------------- 1 | # Yeoman 2 | 3 | Yeoman offers workflow tools: 4 | 5 | * Yo for webapp scaffolding 6 | * Bower for dependency management 7 | * Grunt for building, testing, and previewing 8 | 9 | #### Yo 10 | 11 | Yo scaffolds your webapps with generators, much like Rails. 12 | 13 | 1) First, install the generators you want to use via npm: 14 | 15 | npm install -g generator-webapp 16 | 17 | The Yo generators follow this generator- convention, so it should also be easy to find generators like generator-angular 18 | 19 | 2) Any of these packages prefixed with generator- can be used with the `yo` command, dropping the `generator-` portion: 20 | 21 | yo webapp 22 | 23 | #### Bower 24 | 25 | * Manages and installs dependencies 26 | * Hosts remote packages like RubyGems to make them easier to install like `bower install query` 27 | * Supports search of its repositories like `bower search angular` or `bower search`, which returns all repos 28 | * Does not handle script concatenation, minification, or module loading like RequireJS or Sprockets 29 | 30 | #### Grunt 31 | 32 | Command line task runner for Javascript. Handles repetitive tasks like minification, compilation, unit testing, linting, etc. 33 | 34 | -------------------------------------------------------------------------------- /Input Roles.md: -------------------------------------------------------------------------------- 1 | # Input Roles 2 | 3 | When considering how to collect input for a method, we're thinking about how to map the inputs that are available to the roles the method would ideally interact with. Collecting input isn't just about finding needed inputs--it's about determining how lenient to be in accepting many types of input, and whether to adapt the method's logic to suit the received collaborator types. 4 | 5 | We have several strategies for ensuring a method has collaborators which can be relied upon to play their assigned roles: 6 | 7 | 1) Coerce objects into the roles we need them to play 8 | 2) Reject unexpected values which cannot play the needed roles 9 | 3) Substitute known-good objects for unacceptable inputs 10 | 11 | # Guard the Borders 12 | 
Like customs checkpoints at national boundaries, we want to guard the inputs coming in at the borders of our code, which allows the rest of our methods to speak confidently about how they interact with the various objects in our code. If we think of objects in terms of neighborhoods, we can rely on just a few "interfacer" objects to act as gatekeepers for our code. Once objects pass through this border guard, they can be implicitly trusted to be good neighbors. 13 | 14 | -------------------------------------------------------------------------------- /Vim Commands.md: -------------------------------------------------------------------------------- 1 | # Vim Commands 2 | 3 | Vim is built on two ideas: 4 | 5 | 1) Modal editing - Vim is entirely keyboard-driven, which allows its users to become blazing fast with it, but also means that keys will have to perform multiple duties. Vim accomplishes this by allowing the editor to shift between a number of modes; command mode, insert mode, and visual mode are the most basic. 6 | 2) Operators - Operators operate over portions of text 7 | 8 | #### Command Mode: 9 | 10 | Command mode allows us to issue different types of commands in the document: 11 | 12 | #### Motions 13 | 14 | The most basic Vim motions are left, down, up, and right, represented by the keys on the home row `H`, `J`, `K`, and `L` respectively. 15 | 16 | Goto Line - `12G` (Goto line 12) 17 | Goto first line - `gg` 18 | Goto last line - `G` 19 | 20 | #### Search and Replace 21 | 22 | Search and replace uses regular expressions in the following format: 23 | 24 | :%s/search/replace/options 25 | 26 | E.g. 27 | 28 | :%s/def/function/g 29 | 30 | The `c` option is unique to Vim, and stands for confirm. It will ask you before performing each substitution. 31 | 32 | 1) /search over text 33 | 2) Make a change 34 | 3) Press `n` to get the next instance 35 | 4) Press `.` to repeat the same change -------------------------------------------------------------------------------- /Collection+JSON.md: -------------------------------------------------------------------------------- 1 | # Collection+JSON 2 | 3 | Collection+JSON (`C+J`) is a media type that has two main benefits over ad hoc JSON documents: standardization (to the extent of machine-parseability) and hypermedia controls (which provide a menu of endpoints for clients to interact with). Clients using `C+J` no longer have to write fiat JSON parsers (at least not at the protocol level), and they no longer have to guess at what endpoints they will be able to interact with, or what valid POST, PUT, and PATCH requests to collection endpoints look like; all this data is contained in a collection template. The query templates provided by `C+J` also describe the ways the client may query for members of the collection. 4 | 5 | ## Profiles 6 | 7 | Collection+JSON documents provide three ways to link to profiles--which can provide application semantics, thus helping to close the semantic gap. 8 | 9 | 1) The profile attribute of the media type header: 10 | 11 | application/vnd.collection+json;profile=http://schema.org/Person 12 | 13 | 2) A link header with the link relation "profile": 14 | 15 | Link: ;rel="profile" 16 | 17 | 3) As a link element: 18 | 19 | "links": [{"link": {"href": "http://example.org/profiles/vcard", "rel": "profile"}}] 20 | 21 | 22 | -------------------------------------------------------------------------------- /Websocket.md: -------------------------------------------------------------------------------- 1 | # Websocket 2 | 3 | Websockets are a part of the HTML5 connectivity specification that formalize a full-duplex, bi-directional communication standard between a client and server. Websockets were created to server a different purpose than the Hypertext Transport Protocol, which was designed to deliver single documents. In recent years, as web pages gradually became web applications, developers have begun filling the gaps between HTTP and real-time applications. We introduced polling, a method of making synchronous requests to the server at a specified interval, which may or may not send back information to update the page with. We introduced long-polling, a similar process in which the server holds requests open until it has data to return, which minimizes the number of HTTP requests and unnecessary HTTP headers in low message volume scenarios, but is just as inefficient in high-interactivity, high message volume projects. 4 | 5 | Sockets on the other hand allow for bi-directional, asynchronous messaging; messages are full-duplex, meaning that both sides can talk at whatever interval they want to. HTTP transactions are half-duplex, like walkie-talkies, which allow only one side to send a message at a time. Websockets improve performance and simplicity of transferring data in web applications. -------------------------------------------------------------------------------- /MEAN.io.md: -------------------------------------------------------------------------------- 1 | # The MEAN.io Setup 2 | 3 | #### The Model Layer 4 | 5 | In the MEAN.io setup, the model layer lives in `app/models/modelName.js`. Each model uses Mongoose to define its schema, set validations, and create static properties (class methods) before using the built-in Mongoose.model function to return a valid Mongoose model object. 6 | 7 | The Model object is compiled using a Mongoose schema object. The Model is a fancy constructor used to instantiate documents in MongoDB, a document-oriented database. 8 | 9 | // Require all necessary files 10 | var mongoose = require('mongoose'), 11 | config = require('../../config/config'), 12 | Schema = mongoose.Schema; 13 | 14 | // Define our schema 15 | var ArticleSchema = new Schema({ 16 | created: { 17 | type: Data, 18 | default: Date.now 19 | }, 20 | title: { 21 | type: String, 22 | default: '', 23 | trim: true 24 | } ... 25 | }); 26 | 27 | // Perform validations 28 | ArticleSchema.path('title').validate(function(title) { 29 | return title.length; 30 | }, 'title cannot be blank'); 31 | 32 | // Define static methods aka class methods 33 | ArticleSchema.statics = { 34 | load: function(id, cb) { 35 | this.findOne({ 36 | _id: id 37 | }).populate('user').exec(cb); 38 | } 39 | }; 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /Localhost.md: -------------------------------------------------------------------------------- 1 | # Localhost 2 | 3 | By default on a Unix machine, localhost will route to `127.0.0.1`, the loopback interface for the computer (http://en.wikipedia.org/wiki/127.0.0.1). 4 | 5 | The name `localhost` is nothing special, just a configuration set in the file `/etc/hosts` on your machine. Running `cat /etc/hosts` on a Mac with the default settings should produce: 6 | 7 | ``` 8 | ## 9 | # Host Database 10 | # 11 | # localhost is used to configure the loopback interface 12 | # when the system is booting. Do not change this entry. 13 | ## 14 | 127.0.0.1 localhost 15 | ... 16 | ``` 17 | 18 | Any other names could be mapped in a similar fashion. `127.0.0.1` is a reserved IP address, which always refers to the loopback interface to your machine, but when your computer acts as a server, it could also serve files or websites from other addresses. `0.0.0.0` is another such reserved address, which instead denotes "all interfaces" on your machine, including `127.0.0.1`. For example, the Ruby on Rails framework listens on `0.0.0.0:3000` by default, signaling that any incoming requests to your computer will be routed to the Rails application. Visiting `0.0.0.0:3000`, `127.0.0.1:3000`, or `localhost:3000` will all route to the Rails application (and each will also route to 127.0.0.1:3000 by default). 19 | 20 | -------------------------------------------------------------------------------- /Partials.md: -------------------------------------------------------------------------------- 1 | # Partials 2 | 3 | Partials are reusable snippets of Rails view code, meaning you can use them to DRY it out. 4 | 5 | #### Install the Rails Partials Package for Sublime Text 2 6 | 7 | 1) Press command shift P 8 | 9 | 2) Select Install Package 10 | 11 | 3) Select Rails Partials 12 | 13 | #### Create a Partial 14 | 15 | 1) Highlight a snippet you want to reuse 16 | 17 | 2) Press alt P 18 | 19 | 3) Name the partial 20 | 21 | 4) Sublime will add the leading underscore and filetype (.html.erb) that denotes a partial 22 | 23 | 5) If you create a partial in the layout file, it _must_ go in app/views/application. If the folder doesn't exist, you'll likely have to move it yourself. 24 | 25 | 6) Render the partial (Sublime will also do this for you): 26 | 27 | <%= render "partial_name" %> 28 | 29 | #### Changing Loops to Partials 30 | 31 | 1) Take your standard each loop: 32 | 33 | @events.each do |event| 34 | <%= event.name %> 35 | <%= event.location %> 36 | end 37 | 38 | 2) Remove the do/end lines: 39 | 40 | <%= event.name %> 41 | <%= event.location %> 42 | 43 | 3) Make it a partial (Alt P, name it). In this case, I named it "event." 44 | 45 | 4) Change the render line to a hash including the collection option: 46 | 47 | <%= render partial: "event", collection: @events %> -------------------------------------------------------------------------------- /Angular Isolate Scopes.md: -------------------------------------------------------------------------------- 1 | # Angular Isolate Scopes 2 | 3 | In many languages, we use modules to break up code into reusable chunks. Modules act as namespaces--containers for a set of identifiers; in Javascript we often call this the execution context. Encapsulating a component's pieces generally ensures that there are standard, known ways into the object (its API, or perhaps a constructor function), and thus known entities that it will be interacting with (provided its concerns are well-defined by the Law of Demeter). 4 | 5 | For instance, a class is another type of namespace that houses class and instance methods--in this example, let's say we have an HTML document formatter that requires knowledge about a document to format: 6 | 7 | class HTMLFormatter < TextFormatter 8 | attr_accessor :document 9 | 10 | def initialize(document) 11 | @document = document 12 | end 13 | 14 | def format 15 | @document.each { |line| markup(line) } 16 | @document 17 | end 18 | 19 | def markup 20 | ... 21 | end 22 | end 23 | 24 | In the case of the HTMLFormatter, we expect it to require a document, and for it to output a document when it's done formatting. It has a well-defined and predictable interface. 25 | 26 | With Angular, we can apply the same encapsulation and public interface design to reusable page components called directives. -------------------------------------------------------------------------------- /Functional Programming in Ruby and JavaScript.md: -------------------------------------------------------------------------------- 1 | # Functional Programming in Ruby and Javascript 2 | 3 | Developers new to Javascript often deride it as being quite unlike what they're used to, and in terms of object-orientation at least, this is a well-made point. But one of the cool benefits of working with Ruby and Javascript is that they're both strongly support functional programming techniques, which in Ruby are often considered "advanced" techniques, but in Javascript are a staple of the language. 4 | 5 | Ruby uses procs, blocks, and lambdas to support flexible, dynamic functional programming: 6 | 7 | %w("the rain in spain").map { |word| word.capitalize } 8 | 9 | By adding a few quick functions to Javascript's library, we can perform the same quick one-liner in Javascript: 10 | 11 | function map(array, funk) { 12 | returnArray = []; 13 | for (i = 0; i < array.length; i++) { 14 | returnArray.push(funk(array[i]); 15 | }; 16 | return returnArray; 17 | }; 18 | 19 | function capitalize(str) { 20 | return str[0].toUpperCase() + str.slice(1); 21 | }; 22 | 23 | map("the rain in spain".split(" "), function(word) { return capitalize(word) }); 24 | 25 | In this way, anonymous functions in Javascript work exactly the same way as blocks or lambdas in Javascript, and can be manipulated on the fly to create highly flexible scripts. 26 | -------------------------------------------------------------------------------- /Dotfiles.md: -------------------------------------------------------------------------------- 1 | Dotfiles 2 | ======================== 3 | Dotfiles rule your configuration. They can dictate the appearance of your command line, let you know which branch of a git repository you're working off of, and much more. 4 | 5 | By default, your dotfiles are invisible and live in the home user directory.To see your dotfiles, open a Terminal window and type: 6 | 7 | defaults write com.apple.Finder AppleShowAllFiles TRUE 8 | 9 | Relaunch Finder, and you'll now be able to navigate to your home user directory and see files like .bashrc and .profile. 10 | 11 | Hiding your dotfiles again is as easy as: 12 | 13 | defaults write com.apple.Finder AppleShowAllFiles FALSE 14 | 15 | If you're new to dotfiles, you're in luck: developers love to share their configurations in libraries such as: 16 | 17 | [GitHub's Dotfiles](http://dotfiles.github.io) and [Dotfiles.org](http://dotfiles.org). 18 | 19 | Launch Academy founder, Dan Pickett, shares his dotfiles at on his [Personal GitHub](https://github.com/dpickett/dotfiles). 20 | 21 | Before you go copying others' work and tinkering around in your dotfiles, be sure to backup your current files. Since dotfiles rule your configuration, they can easily screw up your OS. Having backups to revert to will allow you to tinker safely. 22 | 23 | For a more detailed look at what your individual dotfiles can do, check out our list of dotfiles. 24 | -------------------------------------------------------------------------------- /Computer Networks Coursera- Sockets.md: -------------------------------------------------------------------------------- 1 | # Sockets 2 | 3 | Sockets are a simple abstraction allowing applications to talk to one another across networks. 4 | 5 | Sockets let apps attach to the network at different ports, which provides a form of addressing that allows us to multiplex applications on a single host. 6 | 7 | The socket API consists of a few steps allowing clients to speak with servers: 8 | 9 | 1) Client sends a `connect()` request 10 | 11 | 2) Server echoes `connect()`, and calls `bind()`, which establishes an address for the connection endpoint. 12 | 13 | 3) Server calls `listen()`, declaring that it is prepared to accept connections from the other side. 14 | 15 | 4) Server calls `accept()`, and then waits for a connection from the other side. 16 | 17 | 5) Client calls `connect()`, establishing the connection. 18 | 19 | 6) Server calls `receive()`, and waits for messages to be received, like someone sitting by the telephone waiting for it to ring. 20 | 21 | 7) Client calls `send()`, with a request. 22 | 23 | 8) Client calls `receive()`, waiting for a reply. 24 | 25 | 9) Server receives the request, performs some processing, and then `send()`s some response. 26 | 27 | 10) Client receives the response and acts appropriately. 28 | 29 | 11) Steps 6-10 repeat during the course of the program. 30 | 31 | 12) Client and server call `close()` to close the connection. \ 32 | 33 | -------------------------------------------------------------------------------- /Ruby Sort By.md: -------------------------------------------------------------------------------- 1 | # Ruby Sort By 2 | 3 | Ruby implements a `sort_by` method that takes a block to sort by; let's take a look at how we could create one ourselves: 4 | 5 | #### n log n Complexity (aka, the bad way): 6 | 7 | If we open up the Array class to add a sorter function that takes a block, we could do so by comparing each element via the block like so: 8 | 9 | class Array 10 | def sorter(&block) 11 | self.sort do |x, y| 12 | block.call(x) <=> block.call(y) 13 | end 14 | end 15 | end 16 | 17 | Doing so means that we're calling the block twice for each comparison, resulting in an _n log n_ complexity, but we could rewrite the function to an _n_ complexity. 18 | 19 | #### n Complexity (aka, the good way): 20 | 21 | Let's revise this in long-form so we can see what's going on, and then refactor down to a shorthand that will make our mothers proud: 22 | 23 | def sorter(&block) 24 | return_array = [] 25 | self.each do |x| 26 | return_array << [x, block.call(x)] 27 | end 28 | 29 | self.sort { |x, y| x[1] <=> y[1] }.map { |x| x[0] } 30 | end 31 | 32 | Here we see that we're creating an array of arrays wherein each sub-array consists of the element itself and the result of the call to the block. 33 | 34 | We can use map again to improve this code: 35 | 36 | def sorter(&block) 37 | self.map { |x| [x, block.call(x)] }.sort { |x, y| x[1] <=> y[1] }.map { |x| x[0] } 38 | end -------------------------------------------------------------------------------- /Git Log.md: -------------------------------------------------------------------------------- 1 | # Git Log 2 | 3 | The `.gitconfig` is one of those dotfiles devs tend to spend a lot of time on. After all, you're going to be getting pretty cozy with Git, and gitting it right will make your job a lot easier. So from me, to you, here's my current favorite `git log` option (aliased as `git hist`): 4 | 5 | [alias] 6 | hist = log --pretty=format:'%h %ad (%ar) | %s%d [%an]' --graph --date=short 7 | 8 | Which comes out a little something like this: 9 | 10 | * 2ee1eea 2013-06-07 (2 days ago) | Add writing forms (HEAD, master) [Brett Shollenberger] 11 | 12 | The `git log` allows you to visualize a project's history, and by default, it's a little verbose: 13 | 14 | commit def038298ed4b15de68070ff3347ef788ee73269 15 | Author: Brett Shollenberger 16 | Date: Mon Jun 3 21:14:32 2013 -0400 17 | 18 | Add Database Indices 19 | 20 | But there are also an incredible number of options to personalize `git log`. Pro Git describes a huge number of them, but let's keep it to the classics: 21 | 22 | %H Commit hash 23 | %h Abbreviated commit hash 24 | %T Tree hash 25 | %t Abbreviated tree hash 26 | %P Parent hashes 27 | %p Abbreviated parent hashes 28 | %an Author name 29 | %ad Author date (format respects the --date= option) 30 | %ar Author date, relative 31 | %cn Committer name 32 | %cd Committer date 33 | %cr Committer date, relative 34 | %s Subject -------------------------------------------------------------------------------- /Blocks.md: -------------------------------------------------------------------------------- 1 | # Blocks 2 | 3 | #### Prefer braces for single lines 4 | 5 | # bad 6 | names.each do |name| 7 | puts name 8 | end 9 | 10 | # good 11 | names.each { |name| puts name } 12 | 13 | #### Prefer do...end for multiline blocks, control flow, and method definitions: 14 | 15 | # taste 16 | names.each do |name| 17 | puts name 18 | puts "#{ name } is an okay guy." 19 | end 20 | 21 | #### Avoid do...end for chaining 22 | 23 | # ugly 24 | names.select do |name| 25 | name.start_with?('S') 26 | end.map { |name| name.upcase } 27 | 28 | # beaut 29 | names.select { |name| name.start_with?('S') }.map { |name| name.upcase } 30 | 31 | #### All you can do with a block is associate it with a call to a method via the yield keyword: 32 | 33 | # Define the method 34 | def a_method 35 | puts 'Start of method' 36 | yield 37 | yield 38 | puts 'End of method' 39 | end 40 | 41 | # Pass a block into the yield statement 42 | a_method { puts 'In the block' } 43 | > Start of method 44 | > In the block 45 | > In the block 46 | > End of method 47 | 48 | #### The method and block can have more of a conversation (coroutines) with one another by passing parameters: 49 | 50 | def param_pass 51 | yield('Bert', 'Hola') 52 | yield('Dan', 'Sup') 53 | end 54 | 55 | param_pass { |name, greeting| puts "#{ greeting }, #{ name }!" 56 | > Hola, Bert! 57 | > Sup, Dan! -------------------------------------------------------------------------------- /By Value versus By Reference.md: -------------------------------------------------------------------------------- 1 | # By Value versus By Reference 2 | 3 | In JavaScript, among other languages, the syntax distinguishes between values that are stored or accessed by the value itself, or by a reference to that value. 4 | 5 | The distinction is important: values that are accessed by the value itself are the value you expect them to be: 6 | 7 | var five = 5; 8 | five 9 | >> 5 10 | 11 | By contrast, JavaScript reference values store a pointer to an object on the heap. If you perform an assignment statement like this: 12 | 13 | var obj1 = new CrazyObject(); 14 | obj2 = obj1 15 | 16 | You aren't making a copy of obj1, you're storing a second reference of the pointer to the object stored on the heap. As opposed to copying, you're actually aliasing obj1 as obj2. So when you change a property or method, you change it on both aliases: 17 | 18 | obj1.insanity = 1; 19 | obj2.insanity 20 | >> 1 21 | 22 | #### Primitive Types are Accessed by Value; Object Types are Accessed by Reference 23 | 24 | As shown above, complex data in JavaScript (of which there's only one type--the object type), is accessed by reference (by pointer), and thus is not copied. The primitive JavaScript datatypes (number, boolean, string, null, and undefined) are accessed by value, so they are in fact copied: 25 | 26 | var five = 5; 27 | var six = five; 28 | six 29 | >> 5 30 | six = 6; 31 | six 32 | >> 6 33 | five 34 | >> 5 35 | 36 | -------------------------------------------------------------------------------- /Websockets vs TCP Sockets.md: -------------------------------------------------------------------------------- 1 | # Websockets vs TCP Sockets 2 | 3 | A TCP socket a Unix file descriptor that allow programs to speak to one another. One of types of TCP sockets, SOCK_STREAM, allows for full-duplex (bidirectional) communication between programs on different machines over the internet. 4 | 5 | That sounds pretty good. So we've got a browser and we've got a server somewhere--we can just connect them with SOCK_STREAM and get on with creating our real-time chat app, right? Almost. 6 | 7 | Some programs work great in very similar ways. SSH, Telnet--what could possibly go wrong? Well these well-known applications have well-known ports reserved for them on most machines (22 and 23 respectively). When you SSH onto a remote host, you can pretty much guarantee that the host `sshd` accepted traffic on port 22. 8 | 9 | That's all well and good, but _your application does not have a well-known port_. But there are well-known ports that browsers generally use to connect with servers--the HTTP and HTTPS ports (80 and 443). 10 | 11 | Good, so let's use one of those. The only small problem is: those ports use the HTTP protocol, so we can't even say, "Hello Mr. Server, I'd like to initiate a TCP socket connection with you," unless we dress up our message in all the right headers. 12 | 13 | That's where Websockets come in. They help us initiate a connection over HTTP, request a TCP socket, and then communicate as we would using sockets normally. -------------------------------------------------------------------------------- /Logarithms and Fast Exponentiation.md: -------------------------------------------------------------------------------- 1 | # Logarithms and Fast Exponentiation 2 | 3 | Algorithms are important in computer science--especially the fundamental ones. The faster we can compute basic operations, the more we're able to accomplish in a shorter amount of time. Logarithmic time algorithms execute very quickly; if an algorithm executes in log2n time, it can process 100,000 pieces of data in 20 basic operations. At that rate, we can process inputs of nearly any size. 4 | 5 | We can process exponents in linear time (a number of steps proportional to the size of the input) simply by repeated multiplication: 6 | 7 | b^4 = b * b * b * b 8 | 9 | But we can process exponents in logarithmic time when we make the observation that: 10 | 11 | b^n = (b^n/2)^2 # if n is even 12 | b^n = b * (b^n-1/2)^2 # if n is odd 13 | 14 | This type of algorithm illustrates an important concept related to the "divide and conquer" principle of algorithm design--it pays to divide the job as evenly as possible. It's not a big deal that in the case of an odd exponent that we simply multiply the even problem by the base once; after this important first step, we end up with the same type of algorithm that continues halving the size of the exponent on each iteration. 15 | 16 | In Ruby, we might write this process as: 17 | 18 | def fast_exp(b, n, total) 19 | return total if n == 0 20 | return fast_exp(b*b, n/2, total) if n.even? 21 | fast_exp(b, n-1, total*b) 22 | end -------------------------------------------------------------------------------- /Mongoose Callbacks.md: -------------------------------------------------------------------------------- 1 | # Mongoose Callbacks 2 | 3 | Mongoose provides Javascript object modeling for Node.js/MongoDB applications utilizing Mongo's query interface. Mongoose extends this query interface to include multiple methods for querying, but the one I see most used in APIs is the immediate execution syntax, which requires a callback. 4 | 5 | Javascript's event-driven, asynchronous callbacks are an infamous solution to the issue of single-threading--allowing time-sucking scripts like database queries to be non-blocking by providing a function for the script to execute when it's finished taking its sweet time. 6 | 7 | Mongoose callbacks work the same way--the query executes immediately and we provide a callback to execute when the query is done (database queries are, after all, one of the primary reasons callbacks were invented). The structure of a Mongoose callback is always the same, too, so let's look at that: 8 | 9 | callback(error, results) { }; 10 | 11 | Mongoose will automatically populate the error and results parameters based on the results of the query. One of the two will be `null`--the `error` parameter if the query is successful, and the `results` parameter otherwise. The non-null parameter will be a Mongoose document--an instance of a Mongoose model class--or a collection of Mongoose documents, supposing the query is for all documents matching certain parameters. As a Mongoose document, this object will feature special functionality added by Mongoose for us to tap into. -------------------------------------------------------------------------------- /State Machines.md: -------------------------------------------------------------------------------- 1 | #State Machines 2 | 3 | State machines represent a very big and complex topic in the world of computer science; navigating to the state machine gem's ReadMe file can make grown men cry. But state machines don't have to the be that complicated! 4 | 5 | Take a simple example of moderating a comment for a blog post. The user is able to flag an inappropriate comment. That causes the comment to appear in a review section for the site admin. The site admin then decides whether he or she wishes to approve or remove the comment. Only approved comments are shown. 6 | 7 | First, install the state machine gem: 8 | 9 | gem 'state_machine' 10 | bundle 11 | 12 | Don't forget to add state to your model (string). 13 | 14 | Then edit your model to include states: 15 | 16 | state_machine :initial => :approved do 17 | state :approved 18 | state :flagged 19 | state :removed 20 | 21 | event :flag do 22 | transition :approved => :flagged 23 | end 24 | 25 | event :approve do 26 | transition all => :approved 27 | end 28 | 29 | event :remove do 30 | transition :flagged => :removed 31 | end 32 | end 33 | 34 | Using the all transition means that you can approve a comment no matter what state your record is. 35 | 36 | Congratulations, you just created a state machine! Now you could perform actions such as: 37 | 38 | comment.approve 39 | comment.flag 40 | comment.remove 41 | -------------------------------------------------------------------------------- /Pure Function.md: -------------------------------------------------------------------------------- 1 | # Pure Function 2 | 3 | One of the foundations of functional programming is pure functions--pure functions everywhere, all the time, for everyone! So what's a "pure" function? And why should you care? 4 | 5 | Pure functions: 6 | 7 | 1) Given the same parameters always evaluate to the same result. 8 | 2) Have no side-effects (they do not alter any variables) 9 | 10 | Okay, that sounds like it might be valuable, but it's actually super valuable. You see, programs composed entirely of pure functions are "referentially transparent," which is a fancy way of saying that you could replace the function with the value it produces, and still have the exact same program. It turns out referential transparency has some crazy good benefits: 11 | 12 | 1) Lazy evaluation, which as you might know, leads us to be able to construct: 13 | 2) Infinite data structures -- streams and the like are possible and efficient 14 | 3) Parallelization - Since any computer anywhere any time could evaluate the function and produce the same result, and since the function doesn't rely on or alter any shared context, you could distribute jobs among any number of computers, which turns out to be the way we're primarily scaling nowadays (horizontally) 15 | 4) Memoization - Which seems like a minor benefit in relation to the others, but is nonetheless pretty nice. Since you can replace a function call with its result, and that's what memoization is, you of course can put your money where your mouth is and actually memoize. -------------------------------------------------------------------------------- /Haskell List Comprehensions.md: -------------------------------------------------------------------------------- 1 | # Haskell List Comprehensions 2 | 3 | List comprehensions in Haskell will be familiar to those with a math background, and for those without, they're quite simple. 4 | 5 | A set is a list of distinct (e.g. non-repeating) items. You can get really specific about defining your set: 6 | 7 | The set of natural numbers (aka integers, counting numbers) "such that" a < b < c <= 10. 8 | 9 | The "such that" syntax is where we define and filter our sets. We use a pipe (`|`) to define it: 10 | 11 | ``` 12 | [ (a, b, c) | a <- [1..10], b <- [1..10], c <- [1..10], a < b, b < c] 13 | ``` 14 | 15 | The syntax above reads: the set `(a, b, c)` such that `|` a, b, and c could be in the range `1..10`, where `a < b`, and `b < c`. Set comprehensions illustrate a common pattern in functional programming: start with a set of candidate solutions, and filter them down until a solution is reached. 16 | 17 | For instance, we can use this syntax to find a right triangle where: 18 | 19 | * The lengths of the three sides are all integers 20 | * The length of each side is less than or equal to 10 21 | * The triangle's perimeter (the combined lengths of its sides) is 24 22 | * a^2 + b^2 = c^2 (definition of a right triangle repeated for clarity) 23 | 24 | This is really easy in Haskell--we're so close in the previous example we should be able to taste it: 25 | 26 | ``` 27 | [ (a, b, c) | a <- [1..10], b <- [1..10], c <- [1..10], a < b, a+b+c == 24, a^2 + b^2 == c^2] 28 | 29 | >> [(6,8,10)] 30 | ``` 31 | 32 | -------------------------------------------------------------------------------- /Kestrel.md: -------------------------------------------------------------------------------- 1 | # Kestrels 2 | 3 | In any language that supports higher-order functions (functions that either accept functions as arguments or return functions), programmers can use Kestrels, functions that return a function that returns a constant function. Don't worry if that sounds confusing; let's break it down: 4 | 5 | # function that returns a function 6 | function function_returner() { 7 | return function() {}; 8 | } 9 | 10 | # function that returns a function that returns a constant (non-changing) function 11 | function function_returner(fn) { 12 | return function constant_function_returner() { 13 | return fn; 14 | } 15 | } 16 | 17 | Actually not too complicated, right? But why on earth would we want to use a Kestrel, or "K Combinator?" 18 | 19 | We could use it to perform some intermediary work: 20 | 21 | # Logs out the person in the intermediate stage, but is still able to work with the Person instance 22 | # without explicitly returning `p` 23 | address = Person.find(...) do |p| 24 | puts "Found person #{p}" 25 | end.address 26 | 27 | In short, the block is only around to perform some side-effects. That means Kestrels are also usually useful in object initialization blocks: 28 | 29 | class Contact < Struct.new do 30 | def to_hash 31 | Hash[*members.zip(values).flatten] 32 | end 33 | end 34 | 35 | Rather than return the value of the block, the block performs certain setup within the context of the class, and the new Struct is returned as the class's ancestor. 36 | 37 | -------------------------------------------------------------------------------- /Function Currying.md: -------------------------------------------------------------------------------- 1 | # Function Currying 2 | 3 | Currying is the technique of transforming a function that takes multiple arguments in a way that it can be called as a chain of functions, each with a single argument (partial application). Said another way, currying is taking a function that takes `n` arguments, and splitting it into `n` functions that take one argument, and partial application is calling a function with some number of arguments in order to get a function back that will take many less arguments. 4 | 5 | # Currying in Javascript 6 | 7 | function curryAddition(x) { 8 | return function(y) { 9 | return function(z) { 10 | console.log(x+y+z); 11 | } 12 | } 13 | } 14 | 15 | curryAddition(1)(2)(3); 16 | >> 6 17 | 18 | # Partial Application in Ruby 19 | 20 | @a = proc { |x, y| proc { |z| x + y + z } } 21 | @b = @a[1, 2] 22 | @b[3] 23 | >> 6 24 | 25 | If that all looks pretty theoretical, don't worry. We have other important uses here that can help us DRY up our code: 26 | 27 | call_on_args = proc do |meth, actor, *args| 28 | current_actor = actor 29 | args.each { |arg| current_actor = current_actor.send(meth, arg) } 30 | current_actor 31 | end 32 | 33 | add = call_on_args.curry.(:+) 34 | subtract = call_on_args.curry.(:-) 35 | 36 | increment = add.curry.(1) 37 | decrement = subtract.curry.(1) 38 | 39 | The important thing to notice here is that we're able to use partial application in conjunction with currying to write general functions and then derive different functionality from them as necessary. -------------------------------------------------------------------------------- /Regex Cheat Sheet.md: -------------------------------------------------------------------------------- 1 | # Regexes 2 | 3 | #### A single character of: a, b, or c: 4 | 5 | [abc] 6 | 7 | #### Any single character except: a, b, or c: 8 | 9 | [^abc] 10 | 11 | #### Any single character in the range a-z: 12 | 13 | [a-z] 14 | 15 | #### Any case insensitive character in the range a-z 16 | 17 | [a-zA-Z] 18 | 19 | #### Line starts with: 20 | 21 | ^ # Match URLs starting with blog: /^blog/ 22 | 23 | #### Line ends with: 24 | 25 | $ # Match URLs ending with /$blog/ 26 | 27 | #### Any word boundary: 28 | 29 | \b # Effectively implied. Match URLs containing. /\bblog\b/ is the same as /blog/. 30 | 31 | #### Start of string: 32 | 33 | \A 34 | 35 | #### End of string: 36 | 37 | \z 38 | 39 | #### Any single character: 40 | 41 | . 42 | 43 | #### Any whitespace character: 44 | 45 | \s 46 | 47 | #### Any non-whitespace character: 48 | 49 | \S 50 | 51 | #### Any digit: 52 | 53 | \d 54 | 55 | #### Any non-digit: 56 | 57 | \D 58 | 59 | #### Any word character (letter, number, underscore): 60 | 61 | \w 62 | 63 | #### Any non-word character: 64 | 65 | \W 66 | 67 | #### Capture everything enclosed: 68 | 69 | (...) 70 | 71 | #### a or b: 72 | 73 | (a|b) 74 | 75 | #### Zero or one of a: 76 | 77 | a? 78 | 79 | #### Zero or more of a: 80 | 81 | a* 82 | 83 | #### One or more of a: 84 | 85 | a+ 86 | 87 | #### Exactly 3 of a: 88 | 89 | a{3} 90 | 91 | #### Three or more of a: 92 | 93 | a{3, } 94 | 95 | #### Between three and six of a: 96 | 97 | a{3, 6} -------------------------------------------------------------------------------- /Automating Front-end Workflows.md: -------------------------------------------------------------------------------- 1 | # Automating Frontend Workflows 2 | 3 | #### Developing Your Workflow with Grunt 4 | 5 | Grunt's website features tons of pre-packaged npm modules that can be run from the command line, and built into a workflow to remove the tedium from repetitive tasks like minification, concatenation, running unit tests, etc. To write a Gruntfile, we follow this basic workflow: 6 | 7 | 1) Load the task: 8 | 9 | $ npm install task-name --save 10 | 11 | This will not only install the task, but it will update it in your `package.json`. 12 | 13 | In our Gruntfile, we load the task with grunt's `loadNpmTask` method: 14 | 15 | module.exports = function(grunt) { 16 | grunt.loadNpmTasks('grunt-contrib-concat'); 17 | }; 18 | 19 | 2) Configure the task: 20 | 21 | Each task will have a set of configuration options that you're able to set. For `grunt-contrib-concat`, we could ask that any any Javascript files in `src/js` and its subfolders get concatenated together and output as `dev/app.js` using the `globstar`, which will recurse through subdirectories, and the globbing wildcard matcher `*`, which will match any filename: 22 | 23 | grunt.initConfig({ 24 | concat: { 25 | js: { 26 | src: ['src/js/**/*.js'], 27 | dest: 'dev/app.js' 28 | } 29 | } 30 | }); 31 | 32 | 3) Add the task to the workflow: 33 | 34 | grunt.registerTask('default', 'concat'); 35 | 36 | This adds concat to the default task (what happens when you just run Grunt). With any name other than default, we run the grunt task as: 37 | 38 | $ grunt task-name 39 | 40 | -------------------------------------------------------------------------------- /Insertion Sort.md: -------------------------------------------------------------------------------- 1 | # Insertion Sort 2 | 3 | The insertion sort is an easy-to-understand, but unfortunately inefficient sorting algorithm. The concept is this: we start with the first element in the list, which is trivially sorted (since it is only a single element long): 4 | 5 | [5, 4, 2, 1, 3] 6 | 7 | >> [5] 8 | 9 | Then, we add a single element at a time to the list, ensuring that it is sorted appropriately: 10 | 11 | >> [4, 5] 12 | 13 | And we continue: 14 | 15 | >> [2, 4, 5] 16 | 17 | And so on. You'll notice that any any given point, we will have sorted one more item than the number of iterations we've presently run, and that we've turned our problem into a simple recursion. What does this look like in code? We need to keep track of two state variables, the original index of the current element we're working on positioning (`i`), and the current index of the current element as we position it (`g`): 18 | 19 | def insertion_sort(elements) 20 | i = 1 21 | while (i < elements.length) 22 | g = i 23 | for (g > 0 && elements[g] < elements[g-1]) 24 | elements[g], elements[g-1] = elements[g-1], elements[g] 25 | g -= 1 26 | end 27 | i += 1 28 | end 29 | end 30 | 31 | Simple, but powerful ideas. Unfortunately the worst case complexity is `O(n^2)`, the average case complexity is `O(n^2)`, and while the best case complexity is `O(n)`, the one instance out of all possible permutations of the last (of which there are `n!`, obviously) where the complexity is `O(n)` is when the entire list is already sorted. Not great odds in favor of the insertion sort. -------------------------------------------------------------------------------- /Encrypting Passwords.md: -------------------------------------------------------------------------------- 1 | # Encrypting Passwords 2 | 3 | Often, we'll want to protect our users by requiring: 4 | 5 | 1) A password to match a "password confirmation" entry (make the user enter the password twice to minimize typos) 6 | 7 | 2) Encrypting their passwords in our database 8 | 9 | We'll then authenticate users via an _authenticate_ method, which will: 10 | 11 | * Encrypt a submitted password 12 | 13 | * Compare it to the stored encrypted password 14 | 15 | * And return the user object or false 16 | 17 | Here's how we'll get it done: 18 | 19 | 1) Add bcrypt-ruby to your Gemfile 20 | 21 | 2) Add a password_digest column to your user model. 22 | 23 | > Note: The name password_digest is essential for the bcrypt-ruby magic to work correctly. The "digest" portion of the name refers to its cryptographic origins--this is the column that will store our encrypted hash. 24 | 25 | 3) `bundle` 26 | 27 | 4) `rake db:migrate` 28 | 29 | 5) Allow :password and :password_confirmation to be mass assigned; we'll need to check them on the model although we won't save them in the database. 30 | 31 | model User < ActiveRecord::Base 32 | attr_accessible :email, :password, :password_confirmation 33 | ... 34 | 35 | You're ready to go! Check out our authenticate method: 36 | 37 | user = user.find_by_email("brett.shollenberger@gmail.com") # We need a user to authenticate first 38 | user.authenticate("foobar") 39 | # 40 | -------------------------------------------------------------------------------- /IIFEs in Coffeescript.md: -------------------------------------------------------------------------------- 1 | #IIFEs in CoffeeScript 2 | 3 | Javascript's Immediately Invoked Function Expressions are a common paradigm for loading things like Backbone/Marionette applications. IIFEs, as their name suggests, are called as soon as they are evaluated, and then never called again--perfect for performing setup on an Application object and returning it to a property hanging off the window. 4 | 5 | (function() { 6 | this.Demo = (function(Backbone, Marionette) { 7 | App = new Marionette.Application(); 8 | 9 | ...perform setup... 10 | 11 | return App; 12 | })(Backbone, Marionette); 13 | }).call(this); 14 | 15 | // The call(this) paradigm is used by Backbone, Coffeescript, and others to explicitly declare the current value of this as the value of this in the IIFE. In our case, this will be the window object, which is the same as if we had invoked the function as a function (); 16 | 17 | The function above will run immediately on setup, providing our window object with access to the Demo application: 18 | 19 | Demo 20 | > Marionette.Application {_regionManager: Marionette.RegionManager.Marionette.Controller.extend.constructor, ... 21 | 22 | // More explicitly: 23 | window.Demo 24 | // Returns the application as well 25 | 26 | Cool, but we can't write that in CoffeeScript, right? Wrong. CoffeeScript's _do_ function performs the same setup: 27 | 28 | @demo = do (Backbone, Marionette) -> 29 | App = new Marionette.Application 30 | 31 | ... perform setup ... 32 | 33 | App // Use CoffeeScript's implicit return 34 | 35 | Much more concise, and easier to read. Win win. -------------------------------------------------------------------------------- /Rails Middleware.md: -------------------------------------------------------------------------------- 1 | # Rails Middleware 2 | 3 | Rails middleware exists as a filtering layer to intercept a request and handle responses differently as that request goes to our Rails application. To understand middleware in Rails, we have to know a bit about Rack applications; Rails middleware are simply Rack applications. 4 | 5 | Rack wraps HTTP requests and responses in the simplest possible way in order to unify and distal the API for web servers, web frameworks, and middleware into a single `call` method. A Rack endpoint accepts requests, calls its `call` method, and returns a response. Rails controllers themselves are just Rack endpoints. 6 | 7 | In Rails 4, we can create a Rack middleware by placing it in `app/middleware/middleware_name.rb`. This file should define a class that has (at least) an `initialize` and a `call` method. The `initialize` method will be passed our Rails application, and our `call` method will be passed our environment. 8 | 9 | class MyMiddleware 10 | def initialize(app) 11 | @app = app 12 | end 13 | 14 | def call(env) 15 | @status, @headers, @response = @app.call(env) 16 | [@status, @headers, self] 17 | end 18 | 19 | def each(&block) 20 | block.call("") if @headers["Content-Type"].include? "text/html" 21 | @response.call(&block) 22 | end 23 | end 24 | 25 | Whatever the value of the response we return, that response must respond to an `each` method, and return string values. The body itself should not be an instance of string. As a Rack reminder, a Rack endpoint should return an array containing the values of the response status, headers, and body. 26 | 27 | -------------------------------------------------------------------------------- /Creating A Good GitHub Page.md: -------------------------------------------------------------------------------- 1 | # Creating A Good GitHub Page 2 | 3 | A good GitHub profile consists of three types of files: 4 | 5 | * How Tos, Style Guides, and Examples 6 | * Libraries, gems, and other bootstrappers 7 | * Finished apps 8 | 9 | In general, you want your GitHub page to showcase your talents and work you've done to give back to the community. These three types of files do that well. 10 | 11 | Let's examine [ThoughtBot's GitHub account](https://github.com/thoughtbot) to see these three filetypes in action. 12 | 13 | * Examples of How Tos, Style Guides, and Examples: 14 | * [Guide to Programming in Style](https://github.com/thoughtbot/guides) 15 | * [Example of Agile Development through a Heroku App (as part of a webinar](https://github.com/thoughtbot/webinar)) 16 | * Examples of Libraries, Gems, and Bootstrappers: 17 | * [Bourbon: A Mixin Library for Sass](https://github.com/thoughtbot/bourbon) 18 | * [Dotfiles](https://github.com/thoughtbot/dotfiles) 19 | * [Paperclip: A Library for Active Record](https://github.com/thoughtbot/paperclip) 20 | * Examples of Finished Apps (you know what these look like): 21 | * [Paperclip Example App](https://github.com/thoughtbot/paperclip_demo) 22 | 23 | With these three types of files, you'll also achieve an active commit history--another emblem of a strong GitHub page. 24 | 25 | Some other examples of strong GitHub pages include; 26 | 27 | * [Terrible Labs](https://github.com/terriblelabs) 28 | * [General Assembly](https://github.com/generalassembly) 29 | * [Vermonster](https://github.com/Vermonster) 30 | 31 | To schedule a one-on-one with Brett to review your GitHub account, email: brett@launchacademy.co 32 | -------------------------------------------------------------------------------- /Database Speed vs Durability.md: -------------------------------------------------------------------------------- 1 | # Database Speed vs Durability 2 | 3 | Database designers make tradeoffs between high speed writes (speed) and assurance that all data written has been done so reliably (durability). An inverse relationship exists between speed and durability; writing to magnetic HDD is orders of magnitude slower than writing to RAM, but in the event of an unclean shutdown (a power outage, for example), everything written to RAM will be lost. Although some databases like memcached rely exclusively on RAM, and are extremely fast, they're also extremely volatile, and designers usually make compromises between speed and durability. 4 | 5 | MongoDB allows users to mediate this issue themselves by selecting a write semantic and whether or not to enable journalling. 6 | 7 | The two write semantics are fire-and-forget and safe mode. Fire-and-forget writes are sent across a TCP socket without requiring a response from the database--inherently, there's no assurance that the write has been saved successfully. Safe mode writes have a degree of customization; by default they will require a response from the database that ensures the data was received without errors, but they can also be used to do things like block until a write has been replicated across a certain number of servers. For high volume, low importance data, fire-and-forget methodologies can work well; for high importance data, safe-mode is important. 8 | 9 | Journalling will provide even more assurance of committed data than safe mode. By default, journalling is enabled in MongoDB, and will commit every write to a log that can be used to ensure files are restored to a consistent state should you lose the server temporarily. -------------------------------------------------------------------------------- /Prototypal Inheritance.md: -------------------------------------------------------------------------------- 1 | # A Treatise on Prototypal Inheritance 2 | 3 | In 1809, fifty years before Darwin released _Origin of the Species_, Jean-Baptiste Larmarck released _Zoological Philosophy_, which detailed his proposed mechanism for evolution, the "inheritance of acquired traits." Though Lamarck's work is just a piece of historical trivia in the scientific world, it can teach us a lot about prototypal inheritance in Javascript, and how it differs from traditional class-based inheritance. 4 | 5 | The idea goes that as an organism lived, it acquired certain characteristics--a certain speed at which it ran, muscles it bulked through repeated use, a set of mental faculties. These acquired characteristics were then passed on to its progeny. Obviously, this isn't how biological inheritance works, but it is how prototypal inheritance works; a prototype is itself an object, and its characteristics serve as a template for other objects that declare it as a prototype. The new objects can override characteristics they acquired from their parent, and in turn serve as prototypes for other objects. 6 | 7 | Class-based inheritance systems are akin to scientific species; they serve as broad templates that don't refer to individuals in the species. Tigris is a species referring to a large type of cat, but it isn't itself a tiger. Tigris is itself a subclass of Panthera (the genus), and so on and so forth. The difference is that in Javascript, constructor functions and prototypes are themselves objects that are non-distinct from the objects that inherit from them. While classes don't obtain new properties at run time, objects can, and objects that serve as prototypes that acquire new traits continue to pass the new traits on to their progeny. -------------------------------------------------------------------------------- /Javascript Type Checking.md: -------------------------------------------------------------------------------- 1 | # Javascript Type Checking 2 | 3 | Javascript is a dynamically typed language, which means that at times we'll want to be certain that objects are of a given type before proceeding with a function. 4 | 5 | #### Foolproof Type Checking 6 | 7 | The `typeof` operator doesn't always provide the response expected; `variable.constructor` usually works better: 8 | 9 | | variable | typeof var | var.constructor | 10 | | ------------- |-------------| -----| 11 | | {an: 'object'}| object | Object | 12 | | ['an', 'array'] | object | Array | 13 | | "a string" | string | String | 14 | | 5 | number | Number | 15 | | function() {} | function | Function | 16 | | true | boolean | Boolean | 17 | | new User() | object | User | 18 | 19 | #### Strict Type Checking 20 | 21 | We can also write functions that strictly check all arguments passed in meet the expected types, and that the correct number of arguments is passed: 22 | 23 | function strict(types, args) { 24 | if (types.length != args.length) { 25 | throw "Invalid number of arguments. Expected " + types.length + "; received " + args.length + " instead"; 26 | } 27 | for (var i = 0, l = args.length; i < l; i++) { 28 | if (args[i].constructor != types[i]) { 29 | throw "Invalid argument type. Expected " + types[i].name + "; received " + args[i].constructor.name + " instead."; 30 | } 31 | } 32 | } 33 | 34 | And use like so: 35 | 36 | function listUsers(prefix, num, users) { 37 | strict([String, Number, Array], arguments); 38 | 39 | for (var i = 0; i < num; i++) { 40 | console.log(prefix + ": " + users[i]); 41 | } 42 | } 43 | 44 | Type checking can improve the flexibility of methods you write to better adapt to the developers that use your code. 45 | 46 | 47 | -------------------------------------------------------------------------------- /Domain-Specific API Design.md: -------------------------------------------------------------------------------- 1 | # Domain-Specific API Design 2 | 3 | Although not widely implemented, standards do exist to improve the machine-readability of web APIs; in particular, hypermedia formats, and predictable formatting as in Collection+JSON can greatly improve the ability of applications to drive other applications. But even if these standards were widely adopted, there would be another, larger challenge to API design: conveying the semantics of a domain in a manner predictable enough for a machine to read. 4 | 5 | To begin designing domain-specific APIs in machine-readable ways, it helps to view the commonalities between many of today's APIs. Today's APIs: 6 | 7 | * Deal with problems too complex to be understood all at once, so they're split into multi-step processes 8 | * Begin the client at the same first step 9 | * After each step in the process, the server provides the client with a number of possible next steps 10 | * At each step, the client decides which step to take 11 | * The server knows what counts as success, and when to stop 12 | 13 | Since the client is ideally a layer built atop the server, it should use these characteristics to call down to the server, without coupling itself to the server's implementation details. This can be achieved by designing a domain-specific format representing the problem domain that incorporates hypermedia controls, which provide the potential next steps to the client and inform the browser of how to structure its HTTP requests, what response to expect, and suggesting how the client should incorporate each step into its workflow. 14 | 15 | ### Stealing Application Semantics 16 | 17 | Without hypermedia controls, resources become the "prize at the end of the maze" of hypermedia controls. They're dead-end resources that don't suggest other related resources to move to next. -------------------------------------------------------------------------------- /Array Iterators.md: -------------------------------------------------------------------------------- 1 | # Array Iterators 2 | 3 | Like all classes that include the Enumerator module, Array has an each method which defines which elements should be iterated over and how. It then defines additional methods defined in terms of each. 4 | 5 | #### Array.each 6 | 7 | a = [10, 20, 30] 8 | a.each { |num| print num -= 10, " " } 9 | >> 0, 10, 20 >> [10, 20, 30] # Array remains unchanged 10 | 11 | #### Array.reverse_each 12 | 13 | a = %w(rats live on no evil star) 14 | a.reverse_each { |word| print "#{ word } " } 15 | >> star evil no on live rats 16 | 17 | a.reverse_each { |word| print "#{ word.reverse } " } 18 | >> rats live on no evil star 19 | 20 | #### Array.map used to create a new array using modified values 21 | 22 | a = [1, 2, 3] 23 | z = a.map { |num| num + 1 } 24 | >> [2, 3, 4] 25 | a 26 | >> [1, 2, 3] 27 | 28 | a.map! { |num| num + 1 } 29 | >> [2, 3, 4] 30 | a 31 | >> [2, 3, 4] 32 | 33 | #### Non-destructive selection: Array.select, Array.reject, Array.drop_while 34 | 35 | a = [1, 2, 3, 4, 5, 6] 36 | a.select { |num| num > 3 } 37 | >> [4, 5, 6] 38 | 39 | a.reject { |num| num < 4 } 40 | >> [4, 5, 6] 41 | 42 | a.drop_while { |num| num < 4 } 43 | >> [4, 5, 6] 44 | 45 | #### Destructive selection: 46 | 47 | a.select! { |num| num > 3 } 48 | >> [4, 5, 6] 49 | 50 | a.reject! { |num| num < 4 } 51 | >> [4, 5, 6] 52 | 53 | a.delete_if { |num| num < 4 } 54 | >> [4, 5, 6] 55 | 56 | a.keep_if { |num| num > 3 } 57 | >> [4, 5, 6] 58 | 59 | a 60 | >> [4, 5, 6] 61 | 62 | #### Array.each_with_index 63 | 64 | a = [10, 5, 2, 1] 65 | a.each_with_index { |value, index| puts "#{ value } is at index #{ index } } 66 | 67 | >> 10 is at index 0 68 | >> 5 is at index 1 69 | >> 2 is at index 2 70 | >> 1 is at index 3 -------------------------------------------------------------------------------- /Javascript Recipe Cheat Sheet.md: -------------------------------------------------------------------------------- 1 | # Javascript Recipe Cheat Sheet 2 | 3 | ## Apply and Call 4 | 5 | Functions are applied with `()`. They also have _methods_ for applying them to arguments. `call` and `apply` set the function context explicitly. 6 | 7 | plus.apply(this, [2, 3]) 8 | 9 | ## Slice 10 | 11 | Arrays have a `slice` method. The function can always be found at `Array.prototype.slice`. It works like this: 12 | 13 | [1, 2, 3].slice(0) 14 | >> [1, 2, 3] 15 | 16 | [1, 2, 3].slice(1) 17 | >> [2, 3] 18 | 19 | [1, 2, 3, 4, 5].slice(1, 4) 20 | >> [2, 3, 4] // The 1st position up to but not including the 4th position 21 | 22 | Note that slice always creates a new array, so `slice(0)` makes a copy of an array. The arguments pseudo-variable is not an array, but you can use `slice` with it like this to get an array of all or some of the arguments: 23 | 24 | var __slice = Array.prototype.slice; 25 | 26 | function argumenter() { 27 | var args = __slice.call(arguments, 0); 28 | for (var arg in args) { 29 | console.log(arg); 30 | } 31 | } 32 | 33 | ## Concat 34 | 35 | Arrays have another useful method, `.concat`. Concat returns an array created by concatenating the receiver with its argument. 36 | 37 | [1, 2, 3].concat([4, 5]) 38 | >> [1, 2, 3, 4, 5] 39 | 40 | Note that `concat` also creates a new array, regardless of whether or not there's anything to be concatentated: 41 | 42 | [1, 2, 3].concat(); 43 | >> [1, 2, 3]; 44 | 45 | var a = [1, 2, 3]; 46 | 47 | a.concat() == a; 48 | >> false 49 | 50 | ## Function Lengths 51 | 52 | Functions have a `length` property that counts the number of arguments declared: 53 | 54 | function(a, b, c) {}.length 55 | >> 3 56 | 57 | This is most often used when overloading a function with abilities based on the arguments passed to it. 58 | -------------------------------------------------------------------------------- /Null Object Pattern.md: -------------------------------------------------------------------------------- 1 | # Null Object Pattern 2 | 3 | Well-meaning code can often get itself into quite a mess when nil values are involved. Nil is like the concept `null`, which means "the absence of a value" or "the value is unknown." The problem lies in methods that expect a certain input type, but get nil instead: 4 | 5 | def log(msg, logger=nil) 6 | if logger && logger.info logger.info msg 7 | end 8 | 9 | The `log` method wants a logger, but if no logger is provided, it ends up with `nil`. The problem here is that the expected `logger` would respond to the `info` method, and `nil` doesn't have an `info` method--we end up with a loud `NoMethodErrror`, but we didn't want our logger to break--we just wanted it to do nothing. 10 | 11 | The problem with `nil` is that it is too generic for many use cases. We don't want a general absence of value as an input--we want the concept of "no logger" as an input. I'm thinking of `NoLogger` as `/dev/null`--the UNIX Null I/O Device, which takes messages as input like a standard I/O device, and promptly discards them. Its stream is `NoStream`. It outputs to `Nowhere`. These may seem like funny questions to ask a non-existent device, but they are precisely the type of questions you would ask about `/dev/null`. You would not ask `/dev/null` what its account balance is, but you might rightly ask the `NoBankBalance` class. 12 | 13 | I'm talking about modeling different concepts of nothing because they are different. We always have domain logic for the "happy path," where everyone has money in the bank and I/O devices to write to, but we often fail to treat the absence of these objects as paradigms to describe in and of themselves. `NoDevice` takes messages and discards them. `NoBalance` has a `balance` of 0, and `pretty_print`s its statement to `$0.00`. These are distinct concepts within their domain for fleshing out the edge cases. -------------------------------------------------------------------------------- /Node.md: -------------------------------------------------------------------------------- 1 | # Node 2 | 3 | Node is a runtime environment and a library--it's a Javascript implementation outside of the browser and a collection of modules to extend Javascript. 4 | 5 | What really differentiates node is that when we write applications, we not only implement our application, we also implement an HTTP server. Not only is this different from other Javascript frameworks, which don't have the ability to serve webpages, it's also different from working in languages like Ruby, Python, and PHP, which don't handle the HTTP request hand-off and page serving in the language itself. 6 | 7 | #### Writing a Basic Server 8 | 9 | Since node is part-library, it contains useful modules for us to do good things like implement servers. The library we'll want to include to get started is HTTP, which contains, as we might expect, a tasty API for creating web servers. Let's look at an example of a static server: 10 | 11 | var http = require("http"); 12 | 13 | http.createServer(function(request, response) { 14 | response.writeHead(200, {"Content-Type": "text/plain"}); 15 | response.write("Hello World"); 16 | response.end(); 17 | }).listen(8888); 18 | 19 | Now the gist of what's going on should be fairly easy to parse--we're returning a header with a 200 status code and a plain text body reading "Hello World." Visiting port 8888 shows us a successfully returned HTTP response, but what exactly's going on here? 20 | 21 | `createServer` returns a new server object, which expects a `requestListener`, a function that's automatically added to the `request` event. The request event is automatically emitted each time there's a request. Thus the `createServer` function in the example returns the same static response object every time it receives an HTTP request. The returned HTTP server object has a method named listen that can take the port name to listen to, as we've done here. -------------------------------------------------------------------------------- /Machine Language.md: -------------------------------------------------------------------------------- 1 | # Machine Language 2 | 3 | Computers can be described concretely--in terms of their hardware architecture--and abstractly--in terms of the hardware's capabilities. Machine language describes the computer in terms of its capabilities. It is an agreement between hardware developers and software developers regarding how the computer's memory can be manipulated using a processor and a set of registers. 4 | 5 | ##### Memory 6 | 7 | A hardware system's memory is the set of devices that can store data and instructions. From a programmer's perspective, the memory is an array of fixed-width registers called _words_ or _locations_. Each register can store some piece of data, and can be accessed via its address--a unique number specifying which cell holds its data. The memory devices include lookup logic that can find the data stored at a given location. 8 | 9 | ##### Processor 10 | 11 | A processor, or central processing unit, is a device that is capable of performing a fixed set of elementary operations, like arithmetic, boolean logic, memory access, and branching. The processor can store inputs, outputs, and instructions either in memory, or in registers. 12 | 13 | ##### Registers 14 | 15 | While hardware developers know that memory itself is composed of registers (atomic locations capable of holding data of a fixed width), the registers that a processor uses are located in close proximity to the processor itself. Since memory access is a relatively slow operation, the processor uses these local registers for high-speed local memory, in order to execute instructions more quickly. 16 | 17 | ##### Languages 18 | 19 | Each hardware platform has its own formalism--its own machine language agreement describing how to perform elementary operations. In order to write in a given machine language, we have to understand the rules of the game: the hardware's instruction set. -------------------------------------------------------------------------------- /Ruby Blocks.md: -------------------------------------------------------------------------------- 1 | # Manipulating Ruby Blocks for Fun & Profit 2 | 3 | Blocks are ubiquitous in Ruby--and one reason why is because they can be used to control scope. Local variables can exist in the scope of a block, and that scope can be shared between methods and classes, but remain encapsulated within the block to avoid polluting the global namespace. Let's see how: 4 | 5 | # procs are blocks turned into objects 6 | # we can use them to create anonymous scopes that are called immediately 7 | # sharing local variables between them, but keeping them from littering the global namespace 8 | 9 | proc { 10 | events = {} 11 | setups = [] 12 | 13 | Kernel.send :define_method, "event" do |name, &block| 14 | events[name] = block 15 | end 16 | 17 | Kernel.send :define_method, "setup" do |&block| 18 | setups << block 19 | end 20 | 21 | Kernel.send :define_method, "each_setup" do |&block| 22 | setups.each do |setup| 23 | block.call setup 24 | end 25 | end 26 | 27 | Kernel.send :define_method, "each_event" do |&block| 28 | events.each do |name, event| 29 | block.call name, event 30 | end 31 | end 32 | }.call 33 | 34 | # Now we have several methods exposed on the Kernel object, which is mixed into every object, 35 | # including main. However, these methods private manage state with the events and setups 36 | # variables that remain local to the proc 37 | 38 | event "sky_is_falling" do 39 | @sky_height < 100 40 | end 41 | 42 | setup do 43 | @sky_height = 50 44 | end 45 | 46 | # We can also avoid polluting the global namespace by creating "clean rooms," 47 | # objects whose sole purpose is to evaluate our blocks 48 | 49 | env = Object.new 50 | 51 | each_setup do |setup| 52 | env.instance_eval &setup 53 | end 54 | 55 | each_event do |name, event| 56 | puts "ALERT: #{name}" if env.instance_eval &event 57 | end -------------------------------------------------------------------------------- /String Literals.md: -------------------------------------------------------------------------------- 1 | # String Literals 2 | 3 | > This was literally the most beautiful and moving thing I’ve ever heard.
4 | > -- Chris Traeger, Parks and Recreation 5 | 6 | String literals are precisely that: the exact sentences, words, or characters you type in between two quotes. Literally. A string literal in Ruby could be: 7 | 8 | ``` 9 | 'Single quoted' 10 | ``` 11 | 12 | Or 13 | 14 | ``` 15 | "Double quoted" 16 | ``` 17 | 18 | Quite simple, really. The difference between single quotes and double quotes is just how literal your string takes you for. Single quotes take you very, very literally. 19 | 20 | ``` 21 | puts 'Test\ntest' 22 | #> Test\ntest 23 | ``` 24 | 25 | Quite literal, no? Double quotes will handle both ASCII escaped characters (like the newline character we tried to add in the first example), and interpolation (e.g. we can use variables as stand-ins for the strings they represent). 26 | 27 | ``` 28 | puts "Test\ntest" 29 | #> Test 30 | #> test 31 | ``` 32 | 33 | Notice how the newline character is escaped in the double-quoted version. A little less literal, but quite a bit more pragmatic. Let's look at uses for interpolation. Suppose you have an array of shopping items: 34 | 35 | ``` 36 | groceries = ['ice cream', 'chicken tenders', 'instant soup'] 37 | ``` 38 | 39 | A true bachelor's delight. Using interpolation, we can loop over these items to produce some snazzy new strings. 40 | 41 | ``` 42 | groceries.each do | item | 43 | puts "I sure do need #{ item }" 44 | end 45 | 46 | #> I sure do need ice cream 47 | #> I sure do need chicken tenders 48 | #> I sure do need instant soup 49 | ``` 50 | 51 | That was easy. The code examples here have followed the recommendations of the [Ruby Style Guide](https://github.com/bbatsov/ruby-style-guide#strings), which we highly recommend you get into so you can follow the best practices of the Ruby world, and more easily read others' code. 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /Object-Oriented Programming.md: -------------------------------------------------------------------------------- 1 | #Object-Oriented Programming 2 | 3 | Object-oriented programming is much like 18th and 19th century Western history: Primarily concerned with taxonomy. Contemporaries of Erasumus Darwin (Charles' grandfather), up through Charles' own cohort, spent their time codifying the tiny worlds under the microscope, the massive worlds through the telescope, the innumerable varieties of finches and far-away never-before-seens, the vast multiplicities of human sexuality, and anything else they could classify, systemify, and otherwise nail down in a neat little box. 4 | 5 | OOP differs from this codification in purpose: Where the Victorian sexologist sought to understand the geography of perversion, developers seek to create the rules so as to simplify their process (it's the difference between trying to understand the natural order and creating that order). 6 | 7 | Object-oriented programmers divide their worlds (programs) into like parts: These are humans, and humans behave this way. Now when the developer creates an individual human, she doesn't have to declare what characteristics this particular human shares with other humans; she only declares the differences. Saves a lot of work, no? 8 | 9 | These divisions are called [classes](google.com). Classes act as the cookie cutters for the cookies: they define what instances of the classes have in common. 10 | 11 | OOP really is a lot like playing God: You don't do anything yourself; if you want to find out whether a student is taking a particular class this semester, you have to give that student the ability to tell you. Then you ask the student, and the student responds. You can order around the things in the world, but you're confined to doing the things that the things in your world can do. If you want to perform multiplication, you have to teach multiplication to your student, and then ask the student to do the multiplication for you. You don't have infinite super powers: You have to create the tools to solve your problems. 12 | -------------------------------------------------------------------------------- /Underscore Templating.md: -------------------------------------------------------------------------------- 1 | # Underscore Templating 2 | 3 | Underscore, a prominent Javascript utility library, contains a microtemplating function that provides a good illustration of how templating works in many frameworks. 4 | 5 | 1) First, we write an HTML template utilizing Underscore's special syntax for interpolation (`<%= interpolated.data %>`), HTML escaping (`<%- html.escaped.data %>'), and arbitrary script evaluation (`<% %>`). 6 | 7 | We could either write our template directly in our Javascript, or between ` 18 | 19 | # app.js 20 | var rawHTML = $('#name-template').html(); 21 | 22 | 2) Now that we have raw HTML, we can utilize Underscore's `_.template` function to transform the template into a templating function. A templating function compiles the HTML we laid out above into a script that's ready to fill in the blanks in our template (but hasn't done so yet). Later, we'll be able to evaluate this function by passing in the data the template requires to become fully-formed: 23 | 24 | # app.js 25 | var template = _.template(rawHTML); 26 | 27 | 3) Let's go ahead and fill in the template: 28 | 29 | var troy = template({person: {name: "Troy"}}); 30 | >>

Troy

31 | 32 | var abed = template({person: {name: "Abed"}}); 33 | >>

Abed

34 | 35 | That's pretty easy, right? 36 | 37 | 4) We can use this template whenever we want to add a new person to our page, and script its entry into the page with jQuery: 38 | 39 | function addPerson(person) { 40 | $('#people').append(person); 41 | } 42 | 43 | $('#new-person').on('submit', addPerson); 44 | 45 | http://jsfiddle.net/6NNfS/9/ 46 | http://jsfiddle.net/8Z94Z/6/ -------------------------------------------------------------------------------- /Symbols.md: -------------------------------------------------------------------------------- 1 | # Symbols 2 | 3 | > Every reference to a symbol takes up the same space, so using symbols for hash keys, links, and routes is always much more efficient than using strings as keys. 4 | 5 | Like integers, which always have the same [object ID](http://google.com) in a given program, symbols maintain the same object ID throughout a program. 6 | 7 | # Strings as hash keys use multiple object IDs, and therefore more memory. 8 | patient1 = { 'ruby' => 'red' } 9 | patient2 = { 'ruby' => 'programming' } 10 | 11 | # Notice the two object IDs for the strings 'ruby' are different; they take up separate space in the 12 | # program. 13 | patient1.each_key { |key| puts key.object_id.to_s } 14 | >> 211006 # The object ID for the 'ruby' string key object in patient1 15 | 16 | patient2.each_key { |key| puts key.object_id.to_s } 17 | >> 203536 # The object ID for the 'ruby' string key object in patient2 18 | 19 | #### Instead, consider the following example using symbols as hashes instead of strings. 20 | 21 | # Symbols used as hash keys use the same object ID every time they're referenced in the program. 22 | patient1 = { ruby: 'red' } 23 | patient2 = { ruby: 'programming' } 24 | 25 | # Notice the object IDs are the same. 26 | patient1.each_key { |key| puts key.object_id.to_s } 27 | >> 3918094 28 | patient2.each_key { |key| puts key.object_id.to_s } 29 | >> 3918094 30 | 31 | #### Ruby assigns unique values to symbols for you (the object IDs), which are maintained throughout each reference in the program. They are immutable (incapable of being changed), and are therefore true constants. Hash keys should be immutable, which is another good reason not to use strings as hash keys. 32 | 33 | 34 | ### 1.9 Key: Value Syntax 35 | 36 | # 1.8 and below: 37 | old_section = { 'oboe' => 'woodwind', 'cello' = > 'string', 'drum' => 'percussion' } 38 | 39 | # 1.9 and above: 40 | section = { 41 | oboe: 'woodwind', 42 | cello: 'string', 43 | drum: 'percussion' 44 | } 45 | -------------------------------------------------------------------------------- /Inverse Associations.md: -------------------------------------------------------------------------------- 1 | #Inverse Associations 2 | 3 | Consider the following association: 4 | 5 | class CrazyCatLady < ActiveRecord::Base 6 | has_many :cats 7 | end 8 | 9 | class Cat < ActiveRecord::Base 10 | belongs_to :crazy_cat_lady 11 | end 12 | 13 | [gist id=5625024] 14 | 15 | Now, imagine you did: 16 | 17 | CrazyCatLady.first.cats.first 18 | 19 | OK, this will query the database for the first CrazyCatLady, then query again for all cats associated with that record. Fair enough. But what if we do this: 20 | 21 | CrazyCatLady.first.cats.first.crazy_cat_lady 22 | 23 | Aside from being a bit silly, this does everything the first statement does, then queries the database a third time to find the CrazyCatLady associated with the first cat. But Rails already has this information! *Why* is it querying the database again? 24 | 25 | Rails is a bit dumb about the inverse of an association. You have to specify that an inverse relationship exists, like so: 26 | 27 | class CrazyCatLady < ActiveRecord::Base 28 | has_many :cats, 29 | inverse_of: :crazy_cat_lady 30 | end 31 | 32 | class Cat < ActiveRecord::Base 33 | belongs_to :crazy_cat_lady, 34 | inverse_of: :cats 35 | end 36 | [gist id=5688873] 37 | 38 | With this done, when we issue: 39 | 40 | CrazyCatLady.first.cats.first.crazy_cat_lady 41 | 42 | We see that Rails won't query the database a third time. We've told Rails that it already knows about the cat's `crazy_cat_lady`. 43 | 44 | So, aside from this contrived example, how are inverse associations useful? Database queries are a precious resource in a web app. Reading and writing to disk are among the most time-intensive activities a server will perform. Too much of these activities, and a queue will start to grow. This results in slow page loads and possibly lost revenue. 45 | 46 | Best practice in many Rails shops is to define `inverse_of` on every relationship. There's really no downside, and plenty of potential benefits. 47 | -------------------------------------------------------------------------------- /Bash_profile vs bash_rc.md: -------------------------------------------------------------------------------- 1 | #bash_profile & .bashrc 2 | 3 | The .bash_profile and .bashrc are the place to put information that only applies to the bash (e.g. the program to start other programs) itself. This information could include alias and function definitions, shell options, and prompt settings. 4 | 5 | By default, these files do not exist on Mac OSX. If you want to run functions from your command line, you should create a .bash_profile and .bashrc file by starting a Terminal window and typing: 6 | 7 | ``` 8 | #> cd ~/ 9 | #> touch .bash_profile 10 | #> touch .bashrc 11 | ``` 12 | 13 | These files will then appear in your home directory. For information on how to view invisible files (all dotfiles are invisible by default) view [Codecabulary: Dotfiles](https://github.com/brettshollenberger/codecabulary/blob/master/dotfiles/dotfiles.md). 14 | 15 | You can now edit these files (they're blank by default) using your favorite text editor. Sublime Text, the Launch Academy editor of choice, can be run from the command line by typing: 16 | 17 | ``` 18 | #> subl filename 19 | ``` 20 | 21 | For information on setting up a [symlink](https://github.com/brettshollenberger/codecabulary/blob/master/generalterms/symlink.md) to Sublime Text, view [Codecabulary: Setting Up Sublime](https://github.com/brettshollenberger/codecabulary/blob/master/sublime/sublime.md). 22 | 23 | What the bash? 24 | ======================== 25 | The .bash_profile is executed for login shells, meaning any Mac OSX Terminal Window by default. Most other graphic user interfaces (GUIs) that emulate terminals tend to use .bashrc instead. 26 | 27 | Since it can be a hassle to maintain two separate configuration files for login and non-login shells, you can source .bashrc from your .bash_profile by adding the following lines to your .bash_profile: 28 | 29 | ``` 30 | if [ -f ~/.bashrc ]; then 31 | source ~/.bashrc 32 | fi 33 | ``` 34 | 35 | And then storing common settings in .bashrc. This change will automatically call .bashrc when you open a console instead of .bash_profile. 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /Observer Pattern.md: -------------------------------------------------------------------------------- 1 | # Observer Pattern 2 | 3 | The observer pattern is a solution to the challenges of creating an integrated system--one where the parts are aware of one another's state, as well as the state of the whole. This problem is particularly challenging to solve in a way that doesn't inexorably couple the classes together in a mess of spaghetti code, and the observer pattern's solution to that challenge is to factor out the observation code into its own distinct concern. 4 | 5 | #### Publishers and Subscribers 6 | 7 | So what exactly does the observer pattern look like? In the days of Facebook and Twitter, it's fairly easy to conceive of a system of publishers and subscribers wherein all your friends or followers receive updates whenever your push them out, and vice versa. 8 | 9 | Under this pattern, a publisher class (often called the "subject" class) has a three primary responsibilities: 1) Manage an extensible list of observers, 2) Provide a simple interface to add or remove observers, and 3) Provide a simple interface to update observers. 10 | 11 | 1) A publisher class should manage an easily extensible list of observers: 12 | 13 | def initialize 14 | @observers = [] 15 | end 16 | 17 | 2) And provide an interface for adding and removing observers: 18 | 19 | def add_observer(observer) 20 | @observers << observer 21 | end 22 | 23 | def remove_observer(observer) 24 | @observers.delete(observer) 25 | end 26 | 27 | 3) And provide a clean interface between the news source and consumers of that news: 28 | 29 | def update_observers 30 | @observers.each { |observer| observer.update(self) } 31 | end 32 | 33 | The Gang of Four defined the observer pattern as being this clean interface between the news source and the consumers, and it's the part of the implementation to focus most on. 34 | 35 | #### Clean News Interface 36 | 37 | I would argue that to provide a truly clean implementation of the observer pattern, your updates should be atomic processes--they should all succeed or fail together, and observers should only be updated when they entire process has been successful: 38 | 39 | -------------------------------------------------------------------------------- /Angular Directives - Advanced.md: -------------------------------------------------------------------------------- 1 | # Advanced Angular Directives 2 | 3 | We can register directives with Angular's dependency injection system via a method on the `$compile` provider that takes a name and a factory function: 4 | 5 | ng.$compileProvider.directive = function registerDirective(name, directiveFactory) { ... }; 6 | 7 | Factory functions are functions that return new objects, much like constructor functions. The difference with the Factory Method Pattern is that it can be used to decide which class to use in a given scenario--meaning that a factory may return different objects based on given parameters (parameterized factory method) or compile objects of different compositions based on given inputs (abstract factory method). The truth is with Angular directives (and with the Factory Method Pattern in general) is that you often won't need to use a factory over a more generalized constructor function, but the composition of all Angular directives requires a factory function, so for most intents and purposes, we'll just need to know that our directives should return an object, but we can keep in mind that as long as a directive returns an object, it doesn't matter what intermediate work is done in the directive, and we can thus create more robust directives using the FMP. 8 | 9 | In Angular-specific terms, the `$compile` provider's `directive` method calls the `$provide` service's `factory` method, which registers the directive with the `$inject` service so that it can be injected as a dependency throughout the rest of the application with the suffix 'Directive', e.g. a directive named slider gets registered as sliderDirective and a directive named navigation gets registered as navigationDirective; these could theoretically be injected into your controllers or other services if you needed access to them, although this is rarely how directives are used in the wild. 10 | 11 | In the wild, directives are generally used to create reusable bits of behavior, templates, or to manipulate the DOM in predictable ways. 12 | 13 | #### Returning Objects versus Returning Functions 14 | 15 | The directive factory function can return an object or a function. -------------------------------------------------------------------------------- /Rails Views Cheat Sheet.md: -------------------------------------------------------------------------------- 1 | # Rails Views Cheat Sheet 2 | 3 | Rails Views files are written in .erb (Embedded Ruby); they _embed_ Ruby evaluations in your HTML. 4 | 5 | #### The erb tag 6 | 7 | <% %> 8 | 9 | The standard erb tag will evaluate the Ruby inside it, but will not print it to the page. It can be used to render HTML conditionally. 10 | 11 | <% if controller.action_name == "index" %> 12 |

You're on the index page

13 | <% end %> 14 | 15 | #### Render erb 16 | 17 | <%= %> 18 | 19 | The added `=` instructs Ruby to render what it evaluates to the page. 20 | 21 | <%= Time.now %> 22 | 23 | Will render: 2013-05-30 15:37:43 -0400 on the page. Without the `=` sign, the contents would evaluate but not render on the page. 24 | 25 | #### The `link_to` helper 26 | 27 | <%= link_to "linked_text", "URI", options hash %> 28 | 29 | The link_to helper is a standard Ruby method (albeit, often written without parentheses), that takes as arguments 1) The anchor text of the link, 2) The URI, and 3) An options hash. Rails helpers often take options hashes in this way in order to give us the flexibility to add arbitrary HTML options without ever leaving Rails. 30 | 31 | <%= link_to "Sample Link", "http://google.com", id:logo %> 32 | 33 | Renders the HTML: 34 | 35 | 36 | 37 | In this way we can dynamically create links using erb. 38 | 39 | #### The stylesheet_link_tag helper and javascript_include_tag helper 40 | 41 | stylesheet_link_tag "application", media: "all" 42 | 43 | Again, these helpers are standard Ruby methods that take as arguments 1) the resource path, and 2) an options hash. The `stylesheet_link_tag` helper, for instance, makes it easier to include all the stylesheets required for a site, which in plain HTML need to be added via the tag. 44 | 45 | Further exploring this example, the stylesheet helper will write a link tag for the `application.css` file, which is standard in your Rails app. By default, `application.css` includes the statement `require_tree`, which also asks the `stylesheet_link_tag` helper to write tags for all the other files in the `app/assets/stylesheets` folder.  46 | -------------------------------------------------------------------------------- /Angular Forms.md: -------------------------------------------------------------------------------- 1 | # Writing Angular Forms 2 | 3 | Angular allows us to write custom form validations, and provides us with a number of directives to tap into. 4 | 5 | 1) The HTML tag form is actually overridden in an Angular app by the form directive, which instantiates FormController, which keeps track of the form's controllers and the state of each field (whether it's been filled out, is valid, invalid, etc). If we add a name for this form, it the form constructor will be published to the current scope, so we can access it easily: 6 | 7 |
8 | 9 | Now form attributes can be accessed like: 10 | 11 | MyGreatForm.name 12 | 13 | And errors for a particular field can be accessed via the $error object: 14 | 15 | MyGreatForm.name.$error 16 | 17 | You'll also notice we've added the `novalidate` attribute to the form field to disable HTML5's default validations, and to allow us to validate via Angular. 18 | 19 | 2) To handle validations, we can use a number of directives; the two most common, however, are `ng-submit`, which is usually used to check whether all form fields are valid on form submission, and `ng-blur`, which is usually used to check individual form fields after a user navigates away from it. 20 | 21 | From a UX standpoint, `ng-blur` is the preferred behavior. It performs validations directly after a user navigates away from a form field; not as they're typing or after they've submitted. It allows a user to declare they're finished with a field, and to receive feedback immediately; filling out the same form twice can cause frustration, and decrease the number of forms users fill out. 22 | 23 | Unfortunately, `ng-blur` is only available on the bleeding edge versions of Angular, not the latest stable release. You can, however, create your own directive to perform the same functionality (https://github.com/brettshollenberger/FacultyUI/tree/master/directives/ngBlur). 24 | 25 | Whichever directive you choose to handle validation, the basic format is to pass the directive the function invocation as a string. Angular's `$parse` service will convert this expression to a function, and call it to handle validations: 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chameleon Template (Chameleon README).md: -------------------------------------------------------------------------------- 1 | Chameleon Template 2 | ================== 3 | 4 | This is the template Chameleon app. When starting a new 5 | Chameleon project, ask Ops to fork this repo to a new one 6 | on GitHub and then work from there. 7 | 8 | 9 | ##Installation 10 | 11 | First install Node.js v0.10.x at http://nodejs.org 12 | 13 | ``` 14 | $ npm install 15 | $ npm install -g bower grunt-cli 16 | # If you get an access error from the above command, run it with sudo: 17 | $ sudo npm install -g bower grunt-cli 18 | $ bower install 19 | $ grunt server 20 | ``` 21 | 22 | ##Config Files 23 | 24 | Config files are located in the `configs` directory. Unless you specify 25 | the ENV variable before running Chameleon, it will default to 26 | `configs/development.json`. To run with production vars: 27 | 28 | ``` 29 | $ ENV=production grunt server 30 | ``` 31 | 32 | Production settings include the following: 33 | 34 | - Auth server is api.edmodo.com 35 | - Image prefix is our CDN URL //assets.edmodo.com/ 36 | - API endpoints are api.edmodo.com/v2.4 for mobile and api.edmodo.com/v3 for One Eye 37 | 38 | Note: at the time of this writing (Feb 5) One Eye has yet to be released, 39 | which means the production URL (api.edmodo.com/v3) won't work. 40 | 41 | 42 | ##Public directories 43 | 44 | In `index.js` we set two public directory locations with Express: 45 | 46 | ```javascript 47 | app.use(express.static(__dirname + '/public')); 48 | app.use(express.static(__dirname + '/bower_components/edmodo-bootstrap/assets')); 49 | ``` 50 | 51 | ##Google Analytics 52 | 53 | 54 | ##Topbar 55 | 56 | - The default topbar is the public version of the Edmodo topbar 57 | - We'll have other topbars for other types of accounts 58 | 59 | 60 | ##Homepage 61 | 62 | The homepage is a simple landing page without any API routes. 63 | 64 | 65 | ##Sessions 66 | 67 | We use the Mozilla client-sessions cookie module (sets and encrypts sessions 68 | on the client). 69 | 70 | We also use Express' session management so traditional testing functionality 71 | continues to work. 72 | 73 | 74 | Qs 75 | == 76 | 77 | Do we copy public Chameleon files from their base directory to the template app? 78 | Or simply point to those files in their directory 79 | -------------------------------------------------------------------------------- /Logarithms And Bits.md: -------------------------------------------------------------------------------- 1 | # Logarithms and Bits 2 | 3 | A single bit is capable of expressing two quantities--0 and 1. In binary, these can represent the numbers 0 and 1. With two bits, we can express the numbers 0, 1, 2, and 3 with the binary expressions `00`, `01`, `10`, and `11` respectively. Notice that each bit is capable of containing one value--on or off (1 or 0), and that in the case where we use two bits to express a value, the first bit represents the presence of a 2, and the second bit represents the presence of a 1. Added together, these bits are capable of expressing the numbers 0-3. Binary expresses values in base 2, where decimal expresses values in base 10. In decimal, we think of the number 1,000 as expressing 1 one thousand, 0 hundreds, 0 tens, and 0 ones. Base two works the same way, except with powers of two instead of powers of 10. `1110`, in binary, expresses the value 14, where the first position represents `2**3`, the second position `2**2`, the third position `2**1`, and the fourth position `2**0` (1). If we add the values with a `1` in that position, we get the number 14. 4 | 5 | How many bits `w` do we need to represent any one of `n` different possibilities, be it one of `n` items or the integers from 1 to `n`? The key observation is that we need at least `n` different bit patterns. Since the number of bit patterns doubles as you add each bit, we need at least w = log2n bits. For instance, if we want to express the numbers 1-4, we need w = log24 (2 bits). 2 bits provides us with exactly four distinct bit patterns, allowing us to represent each of the four values. Those familiar with binary will likely notice, however, that we actually need _3_ bits to represent the number 4, since the 0th bit represents 20, the 1st bit represents 21, and we can't make 4 out of 2 + 1. That's true; the point we're trying to make here is that we are given 4 bit patterns with 2 bits, and that we _could_, under some other system, represent the number 4 this way. Supposing we wanted to actually represent the number 4 on the binary system we actually use, we'd need the ability to represent at least _5_ possibilities, since 0 is our first possibility. Adding one more bit gets us 23=8 values, allowing us to represent the numbers 0-7. -------------------------------------------------------------------------------- /Truthy and Falsy.md: -------------------------------------------------------------------------------- 1 | # Truthy and Falsy 2 | 3 | Little in the "real" world is black and white, but in the world of boolean logic, computers will find a way to evaluate any statement, object, or variable as true or false. As humans, we can conceive of such statements as: 4 | 5 | 1 < 2 ## true 6 | ships.sunk? ## if true, a game of Battleship is over 7 | 8 | But what about statements like: 9 | 10 | if chair ## is a chair inherently true or false? 11 | unless 1 ## what about the number 1? 12 | 13 | These statements would sound more than a little crazy in natural language, but in computer science they often have a sound purpose: to check whether an error has occurred, whether a user has entered some value, or whether something unexpected has happened. 14 | 15 | For instance, we might say: 16 | 17 | if @user 18 | 19 | To determine whether or not a user object exists. This statement will evaluate to true if a user is signed in, and false if a user is not. 20 | 21 | _But Boolean logic varies across languages._ Let's look at some of the differences between Ruby and Javascript: 22 | 23 | | Type | Language | Boolean Value | 24 | | -------------- |:------------------------:|:--------------------------------------------| 25 | | Nil/ null | Ruby/Javascript | False | 26 | | Undefined | Ruby | Does not exist | 27 | | Undefined | Javascript | False | 28 | | Boolean | Ruby/Javscript | True/False | 29 | | Number | Ruby | True | 30 | | Number | Javascript | 0 and NaN are false; else: true | 31 | | String | Ruby | True | 32 | | String | Javascript | True unless empty string | 33 | | Object | Ruby/Javscript | True | 34 | 35 | Knowing the truthiness and falsiness of various types in your languages of choice is important--you can see it's easy to get tripped up when transitioning! -------------------------------------------------------------------------------- /Migrations.md: -------------------------------------------------------------------------------- 1 | # Migrations 2 | 3 | [Rails](http://www.google.com) migrations allow you to alter your database in a structured and organized way. Instead of altering your database using a [Data Definition Language](http://www.google.com) (the most familiar being [SQL](http://www.google.com)), you'll write Ruby code that [Active Record](https://github.com/brettshollenberger/ruby_wiki/blob/master/Active%20Record.md) will translate into the proper DDL commands. There are a few benefits to handling [schema](https://github.com/brettshollenberger/ruby_wiki/blob/master/Schema.md) changes this way: 4 | 5 | * Ruby-fied schema changes via Rails migrations are _database independent_: They aren't written in the DDL of your database, so if you use [SQLite](http://www.google.com) now, and need to transition to [Postgres](http://www.google.com) later, you don't have to change any Ruby code. Active Record will switch to the appropriate DDL for you. 6 | * You don't send your team SQL commands to run: You send them the migrations, which are ordered chronologically. They only have to update to the latest source code and run one command (in the command line, in the [Rails root](https://github.com/brettshollenberger/ruby_wiki/blob/master/Rails%20Root.md)): 7 | 8 | rake db:migrate 9 | 10 | This simple command: 11 | 12 | * Keeps track of all migrations (changes to the [database schema](https://github.com/brettshollenberger/ruby_wiki/blob/master/Schema.md)) for the next time you deploy. 13 | * Keeps everyone's `db/schema.db` up-to-date (file path relative to the Rails root). 14 | * Since migrations are tracked chronologically, when you're ready to update your production code, running `rake db:migrate` will run all the migrations in the same order they were run on the development server: leaving you with an up-to-date database. Try saying that five times fast. 15 | 16 | The only step left for you take care of is to update the [Model class](http://google.com) associated with the changes you made to the schema (making sure you follow the [Migration Naming Convention](https://github.com/brettshollenberger/ruby_wiki/blob/master/Naming%20Migrations.md). 17 | 18 | Click here to learn about [writing a Rails migration](https://github.com/brettshollenberger/ruby_wiki/blob/master/Writing%20a%20Rails%20Migration.md). -------------------------------------------------------------------------------- /Node.js Modules.md: -------------------------------------------------------------------------------- 1 | # Node.js Modules 2 | 3 | Users of node's libraries assign the libraries to variables, and call functions on the public interface on those variables, like so: 4 | 5 | var http = require('http'); 6 | 7 | http.createServer(function(request, response) { 8 | ... 9 | }); 10 | 11 | As creators of modules in node, we also need to expose our public API in some way. Here are a few of the most common: 12 | 13 | #### Expose a Single Function 14 | 15 | One option, if you have a single function as the public interface, is to attach `module.exports` to the function itself: 16 | 17 | module.exports = function() { 18 | public function... 19 | }; 20 | 21 | Now when we require the function, we use it directly: 22 | 23 | var imported_function = require('./my_module'); 24 | 25 | imported_function(); 26 | 27 | #### Expose a Singleton-Type Object 28 | 29 | We could also place a number of publicly accessible functions on the module.exports object itself, so that the module acts as a singleton: 30 | 31 | module.exports.coolFunction = function() { 32 | ... 33 | }; 34 | 35 | var imported_singleton = require('./my_module'); 36 | 37 | imported_singleton.coolFunction(); 38 | 39 | #### Expose a Psuedo-class 40 | 41 | If the module is a class, you can either expose the constructor directly, or expose a function to allow the class to be instantiated: 42 | 43 | var CoolClass = function() { 44 | ... 45 | }; 46 | 47 | CoolClass.prototype.coolFunction = function() { 48 | ... 49 | }; 50 | 51 | module.exports.create = function() { 52 | return new CoolClass; 53 | }; 54 | 55 | Now the module would be used via the `create` method: 56 | 57 | var instance1 = imported_class.create(); 58 | 59 | Although this use case prevents users from silly errors like forgetting the `new` keyword when using the constructor, it violates the Open/Closed Principle. We ought to make our class open to extension. 60 | 61 | Being that that's the case, we can simply expose the class itself: 62 | 63 | module.exports = CoolClass; 64 | 65 | $ var instance1 = new imported_class(); 66 | 67 | And this final method tends to be the right choice for advanced users of our module, since it enables the most flexibility, including the ability to extend our module. 68 | 69 | 70 | -------------------------------------------------------------------------------- /Capybara Cheat Sheet.md: -------------------------------------------------------------------------------- 1 | # Capybara Cheat Sheet 2 | 3 | #### Navigating 4 | visit('/projects') 5 | visit(post_comments_path(post)) 6 | 7 | #### Clicking links and buttons 8 | click_link('id-of-link') 9 | click_link('Link Text') 10 | click_button('Save') 11 | click('Link Text') # Click either a link or a button 12 | click('Button Value') 13 | 14 | #### Interacting with forms 15 | fill_in('First Name', :with => 'John') 16 | fill_in('Password', :with => 'Seekrit') 17 | fill_in('Description', :with => 'Really Long Text…') 18 | choose('A Radio Button') 19 | check('A Checkbox') 20 | uncheck('A Checkbox') 21 | attach_file('Image', '/path/to/image.jpg') 22 | select('Option', :from => 'Select Box') 23 | 24 | #### Scoping 25 | within("//li[@id='employee']") do 26 | fill_in 'Name', :with => 'Jimmy' 27 | end 28 | within(:css, "li#employee") do 29 | fill_in 'Name', :with => 'Jimmy' 30 | end 31 | within_fieldset('Employee') do 32 | fill_in 'Name', :with => 'Jimmy' 33 | end 34 | within_table('Employee') do 35 | fill_in 'Name', :with => 'Jimmy' 36 | end 37 | 38 | #### Querying 39 | page.has_xpath?('//table/tr') 40 | page.has_css?('table tr.foo') 41 | page.has_content?('foo') 42 | page.should have_xpath('//table/tr') 43 | page.should have_css('table tr.foo') 44 | page.should have_content('foo') 45 | page.should have_no_content('foo') 46 | find_field('First Name').value 47 | find_link('Hello').visible? 48 | find_button('Send').click 49 | find('//table/tr').click 50 | locate("//*[@id='overlay'").find("//h1").click 51 | all('a').each { |a| a[:href] } 52 | 53 | #### Scripting 54 | result = page.evaluate_script('4 + 4'); 55 | 56 | #### Debugging 57 | save_and_open_page 58 | 59 | #### Asynchronous JavaScript 60 | click_link('foo') 61 | click_link('bar') 62 | page.should have_content('baz') 63 | page.should_not have_xpath('//a') 64 | page.should have_no_xpath('//a') 65 | 66 | #### XPath and CSS 67 | within(:css, 'ul li') { ... } 68 | find(:css, 'ul li').text 69 | locate(:css, 'input#name').value 70 | Capybara.default_selector = :css 71 | within('ul li') { ... } 72 | find('ul li').text 73 | locate('input#name').value -------------------------------------------------------------------------------- /Starting A Git Project.md: -------------------------------------------------------------------------------- 1 | ## Starting A Git Project 2 | 3 | Git is a version control system that takes snapshots of an entire filesystem over time. As you reach a good stopping point (perhaps you've finished a new feature), you _commit_, or record those changes to the file system along with a message to help you and your team to remember what changes were made in that version and why. 4 | 5 | ![Illustration of the Git VCS. All illustrations in this article, and tons of the tips, were first brought to my attention via the free and wonderful book Pro Git.](http://git-scm.com/figures/18333fig0105-tn.png) 6 | 7 | There are two primary ways to start a Git repo: 1) To start tracking a new or existing, untracked project in Git, or 2) To clone an existing Git repo from another server. 8 | 9 | #### Git Init 10 | 11 | To start tracking a new or existing project in Git, enter the project's directory via the command line and enter: 12 | 13 | git init 14 | 15 | `git init` creates a new subdirectory in the root named `.git` that contains your repo files, although you haven't begun tracking anything yet. Git is very obedient in terms of tracking changes, and will only record the changes you tell it to. We'll explore how to track these changes in the Git Lifecycle section below. 16 | 17 | #### Git Clone 18 | 19 | Your colleague already has a Git repo that you'd like to begin working on. Great. Enter the terminal and enter: 20 | 21 | git clone [url] 22 | 23 | Where other VCSes `checkout` the latest copy of a repo, `git clone` copies every version of every file in the history of the project. No one needs to rely on the server's copy of the repo, or your klutzy friend Andy's copy of the repo (he's always spilling lemonades on his computer). With `git clone`, if one version of the repo is corrupted, you can use any of the clones to get the repo back in top shape. 24 | 25 | git clone git://github.com/user/directory.git 26 | 27 | The command above creates a new directory on your computer (named `directory` in this example), creates a `.git` directory inside of it, pulls down the data for the repo and checks out a working copy of the latest version. 28 | 29 | git clone git://github.com/user/directory.git whatever_i_want 30 | 31 | This command does the same thing, except it names the directory `whatever_i_want` instead of `directory`. -------------------------------------------------------------------------------- /Logarithms And Trees.md: -------------------------------------------------------------------------------- 1 | # Logarithms and Trees 2 | 3 | Trees in computer science can be useful for things like binary search and quickly moving through a list. Since trees can be so important to algorithms, let's take a quick look at some of the semantics of trees: 4 | 5 | 1) Height: Trees must inherently have height. A single node with no connections to other nodes is not a tree--it's a point. By joining points to other points, we can make things like graphs and trees, which describe the relationships between points. In particular, trees tend to describe hierarchical relationships, ancestry, or taxonomy, because they inherently establish dominance relationships between the nodes, while graphs are freer in the types of relationships they describe. 6 | 7 | 2) Leaf nodes: Leaf nodes are also called terminal nodes because they have no child nodes. Terminal nodes help us describe the type of tree we're working with; for instance, a tree which allows each node to have up to two child nodes is called a binary tree, while a tree which allows each node to have up to three child nodes is called a ternary tree, and so on (where "and so on" means continue using your Latin numerical prefixes). 8 | 9 | With just this base knowledge, we might already intuit that logarithms are important to trees. In case you've forgotten from math class, a logarithm describes an algebraic, exponential relationship where the exponent is the variable that's important to us (e.g. 2x = 4). The logarithmic way of writing the same expression is log24 = x (and the logarithmic expression emphasizes that `x` is the value we seek, since we've isolated it). 10 | 11 | Remember, in a binary tree, each node may have `d=2` children. If we want to know how many child nodes a binary tree will have, max, at a certain height, we can use a logarithm to express that value: log2n = h. At `h=1`, `n=2`. At `h=2`, `n=4`. 12 | 13 | In a ternary tree, each node may have `d=3` children, and we can express this with the expression log3n = h. At `h=1`, `n=3`. At `h=2`, `n=9`, and so on. 14 | 15 | For trees in general, we can describe this relationship as logdn = h, where `d = the number of leaf nodes`. 16 | 17 | The important thing to note is that very short tres can have many leaves, which is the main reason why binary trees prove fundamental to the design of fast data structures. -------------------------------------------------------------------------------- /Higher Order Functions.md: -------------------------------------------------------------------------------- 1 | # Higher Order Functions 2 | 3 | Higher-order functions do one or more of the following: 4 | 5 | * Accept a function as an argument 6 | * Return a function as the return value of a function 7 | 8 | Take for example `map` in Ruby: 9 | 10 | # Accepting a function as an argument 11 | 12 | def increment(n) 13 | n + 1 14 | end 15 | 16 | [1, 2, 3].map(&method(:increment)) 17 | 18 | Or currying in Javascript: 19 | 20 | # Returning a function as the return value of a function 21 | 22 | function plusN(a) { 23 | return function(b) { 24 | return a + b; 25 | } 26 | } 27 | 28 | var increment = plusN(1); 29 | 30 | increment(2); 31 | >> 3 32 | 33 | There are several specific types of higher-order functions. 34 | 35 | ## Combinators 36 | 37 | Combinators have a precise technical meaning in mathematics: 38 | 39 | > "A combinator is a higher-order function that uses only function application and earlier defined combinators to define a result from its arguments." 40 | 41 | We can use a looser definition of combinator: 42 | 43 | > "Higher-order pure functions that take only functions as arguments and return a function." 44 | 45 | We won't be strict about using previously defined combinators in their construction. 46 | 47 | ### Practical Combinators 48 | 49 | Code that uses a lot of combinators tends to name the verbs and adverbs (like `double` and `increment`) while avoiding language keywords and the names of nouns. So one perspective is that combinators are useful when you want to emphasize what you're doing and how it fits together, and more explicit code is useful when you want to emphasize what you're working with. 50 | 51 | #### Compose 52 | 53 | Logicians call this the B combinator or "Bluebird", though programmers tend to call it "compose." 54 | 55 | function compose(a, b) { 56 | return function(c) { 57 | return a(b(c)); 58 | } 59 | } 60 | 61 | #### Function Decorators 62 | 63 | A function decorator is a higher-order function that takes one function as an argument, returns another function, and the returned function is a variation of the argument function. Here's a ridiculous example of a decorator: 64 | 65 | function not(fn) { 66 | return function() { 67 | return !fn(arguments); 68 | } 69 | } 70 | 71 | function cool() { return true; } 72 | 73 | var uncool = not(cool); 74 | 75 | uncool(); 76 | >> false -------------------------------------------------------------------------------- /Javascript Ninjahood.md: -------------------------------------------------------------------------------- 1 | # Javascript Ninjahood 2 | 3 | 1) Functions create scopes, blocks do not 4 | 5 | 2) Named functions are forward referenceable, but variables are not 6 | 7 | 3) The browser runs the event loop and dispatches events; there are four types of events: 8 | 9 | * Browser events (page loaded) 10 | * Network events (AJAX request complete) 11 | * User events (mouse clicks, key presses) 12 | * Timer events (request timeout) 13 | * 14 | 4) Functions are first-class objects; they can: 15 | 16 | * Have properties assigned to them 17 | * Be passed as arguments to functions 18 | * Be returned from functions 19 | * Be created with literals 20 | 21 | 5) There are four ways to execute functions in Javascript, and each bears an impact on the value of `this` (the function execution context): 22 | 23 | * As a function. A basic function call in which the window object is the value of `this`. 24 | * As a method: An object-oriented function in which the value of `this` is the object itself (the method's owner). 25 | * As a constructor: Initiates an empty object, which is passed as `this`, initialized, and returned (as long as nothing else is returned from the constructor). 26 | * Via `call` or `apply`: Call and apply are methods of functions. They alter the execution context to be the first argument. The remaining arguments via apply should take the form of an array. 27 | 28 | 6) Function overloading (passing too many parameters to a function) results in the excess parameters not being assigned to named parameters. These are still accessible via the `arguments` hash, however. 29 | 30 | 7) Function underloading (not passing enough parameters to a function) results in the excess parameters being set to `undefined`. 31 | 32 | 8) Named inline functions are no longer anonymous, and can be copied without fear of the original function disappearing: 33 | 34 | var ninja = { chirp: function chirp(n) { return n; } } 35 | var samuari = { chirp: ninja.chirp } 36 | ninja = {} 37 | samauri.chirp(1) 38 | > 1 39 | // It still exists 40 | 41 | 9) Function memoization: 42 | 43 | function myMemoizer(arg) { 44 | if (!myMemoizer.answers) myMemoizer.answers = {}; 45 | if (myMemoizer.answers[arg]) return myMemoizer.answers[arg]; 46 | ... compute answer ... 47 | } 48 | 49 | 10) Using call/apply to get at built-in methods: 50 | 51 | Array.prototype.slice.call(arguments, 1); 52 | 53 | 11) -------------------------------------------------------------------------------- /Template Method Pattern in Angular Templates.md: -------------------------------------------------------------------------------- 1 | # Template Method Pattern in Angular Templates 2 | 3 | Let's say we have model instances that will use much of the same functionality, with slight variances among a given algorithm. We're good programmers, and we don't like to repeat ourselves, so we want to vary the algorithm slightly without writing the same code over and over again--even when we work on the front end. The Template Method Pattern lets us do this, and thanks to Angular's `transclude` property on directives, we can include placeholders for these minor variations in our templates. 4 | 5 | At Faculty Creative, we've been working on a project where our design team asked me to style active projects in color and old projects in black and white. As you might image in, the HTML and LESS for the projects was pretty much the same, with some minor changes to applied classes in a few places. Here's one approach to keeping the code DRY: 6 | 7 | Angular lets us write highly reusable code using directives--custom HTML templates with superheroic abilities. 8 | 9 | angular 10 | .module('app') 11 | .directive('projectQuickView', function() { 12 | return { 13 | restrict: 'E', 14 | replace: false, 15 | templateUrl: 'app/templates/partials/projectQuickView.html', 16 | transclude: true 17 | }; 18 | }); 19 | 20 | In this directive, I've declared that we'll be able to write the directive as an element (` 23 | 24 | ... awesome project layout ... 25 |
26 | 27 | Then for old projects, our layout looks like this: 28 | 29 | 30 | 31 | And for new projects, our layout looks like this: 32 | 33 | 34 | 35 | And presto! We've used the same layout with slight differences for highly reusable code that can also take additional new stylings as we expand the project. Super rad. -------------------------------------------------------------------------------- /Angular Minification.md: -------------------------------------------------------------------------------- 1 | # Angular Minification 2 | 3 | To minify Angular scripts for production, we need to use the array notation for dependency injection: 4 | 5 | angular.module('app', []) 6 | .controller('MyController', ['$scope', function($scope) { }]); 7 | 8 | The reason we do this is because function arguments will get reduced to simple variables by the minifier: 9 | 10 | angular.module('app', []) 11 | .controller('MyController', ['$scope', function(a) { }]); 12 | 13 | With the array notation, it doesn't matter if the variable name gets minified, because it's still able to look up the dependency name using the un-minified string "$scope." In this notation, the order of our arguments matters--we use that order to determine that `a` refers to `$scope`. 14 | 15 | It's important in Angular to understand when array notation is necessary, and when it isn't. When Angular is injecting dependencies--array notation is required. Angular injects dependencies into `services`, including `directives`, `controllers`, `providers`, `factories`, and of course `services` themselves. 16 | 17 | Let's check out the difference between a directive's controller function and its link function (remember, the controller function is _still_ a controller). 18 | 19 | angular.module('directives', []) 20 | .directive('myDirective, function() { 21 | return { 22 | controller: ['$scope', function($scope) { 23 | $scope.myCoolVariable = "cool!"; 24 | }], 25 | link: function(scope, element, attars) { 26 | scope.myOtherCoolVariable = "other cool!"; 27 | } 28 | } 29 | }); 30 | 31 | In the controller function, we have to use the array notation to inject the dependencies. The link function however is a standard function using ordered arguments. We could have also written the arguments like this: 32 | 33 | link: function($scope, $element, $attrs) { }; 34 | 35 | Or even this: 36 | 37 | link: function(element, attrs, grapefruit) { }; 38 | 39 | The first argument in a link function always refers to the scope, the second to the element, and the third to the attributes--no matter what they're called. These are ordered parameters. For this reason, we don't need to protect these against minification. When we use the array notation for dependency injection, we transform the arguments in that function into order parameters, and offer them the same protection, keeping our app safe and happy. -------------------------------------------------------------------------------- /Event-Driven, Asynchronous Callbacks.md: -------------------------------------------------------------------------------- 1 | # Event-Driven, Asynchronous Callbacks 2 | 3 | In languages like Ruby and Python, when a process proceeds slowly, like a massive database query, it proceeds slowly for the user that requests it. In Javascript, there's just one process, and we could quickly encounter global issues that affect all users when just one or two users makes a resource-intensive request. 4 | 5 | Javascript solves this issue differently from Ruby or Python. In each language, there's a basic, procedural means of writing, which proceeds to each command after completing the previous command: 6 | 7 | var records = db.query("SELECT * FROM massiveTable"); 8 | doSomethingElse(); 9 | 10 | Since all users would be affected by the blocking nature of a single user's procedural chain in Javascript, Javascript provides a means of asynchronously completing its tasks. This a asynchronicity is built on three principles: 11 | 12 | 1) _Callback events as function parameters_: If a request could take a while, Javascript lets you provide a callback function as an argument to that function (don't forget, as a functional language, functions can be passed around as first-order objects). 13 | 14 | It uses the callback function as a mental note of what to do when it's finished with the long request, and tells the next command in the procedural chain that it can get started on its work while the lengthy command finishes up its work. 15 | 16 | Instead of the code above, a function with a callback would look like: 17 | 18 | db.query("SELECT * FROM massiveTable", function() { 19 | somethingToDoWhenFinished(); 20 | }); 21 | 22 | 2) _Asynchronous processing_: Built on the back of the callback function, Javascript's procedures can proceed without finishing previous tasks as long as the previous tasks have callbacks to tap into when they're finished. Functions with callbacks will allow the next task to begin after they get to work. 23 | 24 | 3) _Event Loop_: When Javascript has nothing else to do, it enters the event loop, and will continue to cycle through the event loop until a new event occurs. When an event occurs, like the long database request finishes processing, its callback is fired and takes precedence. Since node can only run a single process at a time, only one callback will ever occur at a time, and the rest will wait in line, though there's no guarantee on the order the callbacks will fire in. 25 | 26 | -------------------------------------------------------------------------------- /Writing Acceptance Tests in Capybara.md: -------------------------------------------------------------------------------- 1 | # Writing Acceptance Tests in Capybara 2 | 3 | Capybara comes with a [Domain-Specific Language (DSL)](google.com) for writing descriptive [acceptance tests](google.com). A domain-specific language is a language created to solve a particular set of problems--in the case of specs, the DSL describes the expected functionality of an application in various situations. 4 | 5 | There are several DSLs dedicated to writing specs in Ruby, including [RSpec](https://github.com/brettshollenberger/ruby_wiki/blob/master/Setting%20Up%20RSpec.md) and Test Unit. Capybara's DSL solves an even more granular problem: Writing acceptance tests. 6 | 7 | For that reason, Capybara's DSL extends the most popular testing DSLs, Cucumber, [RSpec](https://github.com/brettshollenberger/ruby_wiki/blob/master/Writing%20Specs%20in%20RSpec.md), Test Unit, and Mini Test. 8 | 9 | Since Capybara's DSL is an extension, the underlying spec DSL can also be used in writing acceptance tests, although the Capybara language will be more useful for writing acceptance tests. 10 | 11 | A traditional Capybara "paragraph" would be laid out like this: 12 | 13 | feature "Sign up" do 14 | background do 15 | User.make(:email => 'user@example.com', :password => 'caplin') 16 | end 17 | 18 | scenario "Signing in with correct credentials" do 19 | visit '/sessions/new' 20 | within("#session") do 21 | fill_in 'Login', :with => 'user@example.com' 22 | fill_in 'Password', :with => 'caplin' 23 | end 24 | click_link 'Sign in' 25 | page.should have_content 'Success' 26 | end 27 | 28 | `feature` is in fact just an alias for `describe ..., :type => :feature`, `background` is an alias for `before`, and `scenario` for `it`. 29 | 30 | Using the Capybara acceptance testing language allows us to assert that the Capybara tests test features, as opposed to more the granular object-functionality approach of unit tests. 31 | 32 | Being that the Acceptance Testing DSL is really just an extension of (and in many ways aliasing of) the RSpec language, readers can get a more detailed look at writing acceptance tests in [Writing Specs in RSpec](https://github.com/brettshollenberger/ruby_wiki/blob/master/Writing%20Specs%20in%20RSpec.md). 33 | 34 | For a more detailed look at Capybara, check out the [Capybara Cheet Sheet](https://github.com/brettshollenberger/ruby_wiki/blob/master/Capybara%20Cheat%20Sheet.md). -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #Codecabulary 2 | 3 | >Think of this wiki as Severus Snape's copy of _Advanced Guide to Potion Making_. The actual contents are canonical: stolen Thoughtbot thoughts and Ruby Style Guide recommendations mixed in with my own marginalia to add clarity and insights helpful to me (and hopefully other young Rubyists). 4 | 5 | >--This Book Is Property of the Half-Blood Prince (kidding) 6 | 7 | It's hard to start programming. Programming itself is easy. It's the starting that's hard. 8 | 9 | I wanted to make the starting easy. When I started, I read books and articles. I went to events. I took classes. I took the fancy web 2.0 classes and I did the code challenges, and the online videos, and the koans in such and such a language. And most of it was hard or bad. 10 | 11 | Most of it is hard or bad for two reasons: 1) Too much jargon and 2) Too little context. 12 | 13 | This wiki tries to solve those problems by: 1) Providing plain-English explanations for technical terms, and 2) Giving the big picture and the tiny details alike. Starting out, you shouldn't be expected to know what the Terminal does or how to use it. You should be guided to the article that will help you figure out the Terminal's essential commands when you do need to know them. That's it. 14 | 15 | This wiki is not a guide (yet). There isn't a path for reading it (yet). Today, as in, on the day you are reading it, it is meant to define terms that sound foreign and to provide their context. 16 | 17 | As of today, this Wiki accomplishes its context task self-referentially. It is the goal of each topic page to explain its topic in detail, and provide links to all topics it relies on to make its point. Some links will take you away from this wiki (to Google) because I've identified them as jargon, but haven't had a chance to define them yet. You shouldn't keep reading if you don't understand a word that I haven't yet defined--you should Google it. That link is my not-so-subtle cue to you to stop if it's not making sense. 18 | 19 | If you'd like me to prioritize a particular term, please email it to me at brett.shollenberger@gmail.com. 20 | 21 | Cheers, 22 | 23 | Brett 24 | 25 | Contributors: [Brett Shollenberger (brettshollenberger)](https://github.com/brettshollenberger), [Michael Raimondi (chronophasiac)](https://github.com/chronophasiac), [Connor Smith (https://github.com/x3igh7)] (https://github.com/x3igh7), [Frank Weber (fweber2)](https://github.com/fhweber2) 26 | 27 | -------------------------------------------------------------------------------- /Angular Filters.md: -------------------------------------------------------------------------------- 1 | # Anglar Filters 2 | 3 | Angular JS is a framework for front-end development, and as such provides filter functionality for working with data--allowing users to search through data, limit the data they see, order the data, etc. 4 | 5 | An Angular filter works by using the pipe character (`|`), and filters can be stacked: 6 | 7 | 8 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 |
ActorCharacter
{{actor.name}}{{actor.character}}
23 |
24 | 25 | 67 | 68 | 69 | 70 | #### Defining Custom Filters 71 | 72 | We can also define custom filters that can be reused throughout our applications. To register a filter, we use the `filter` method, which creates an injectable filter factory, and in our callback we return the filter function: 73 | 74 | app.filter('piglatinize', function() { 75 | return function(line) { 76 | return line.split(' ').map(function(word) { 77 | return word.slice(1, word.length) + word[0] + 'ay'; 78 | }).join(' '); 79 | }; 80 | }); -------------------------------------------------------------------------------- /Angular as MVVM.md: -------------------------------------------------------------------------------- 1 | # Angular as MVVM 2 | 3 | Angular's core team refers to it as MVW--model view whatever--but one way of looking at the framework is as an MVVM implementation. The part here that's likely unfamiliar is the ViewModel, the "model of the view," which exposes a "view API"--data and functionality to the view--and allows the view to update the model through data bindings. 4 | 5 | The ViewModel in Angular are the `$scope` objects. Each `$scope` object represents a node in the DOM tree, exposes a set of functionality to that node in the tree, can update the model, and can inherit functionality from its parents in the tree, though it doesn't have to. Let's take a look at how the view creates `$scope` objects (ViewModel objects): 6 | 7 | 1) Each Angular directive can create a new scope, or use its parent scope: 8 | 9 | <-- ng-app creates $rootScope. Anything exposed on $rootScope is accessible here. --> 10 | 11 | <-- ng-controller creates a new scope that inherits from $rootScope. Anything accessible on either rootScope or MainCtrl's scope is accessible here --> 12 |
13 | {{rootScopeProperty}} {{mainCtrlProperty}} 14 |
15 | 16 | 17 | 2) Your own directives can also create new scopes through the `scope: true` property. This property ensures that the new scope will inherit from its parent scope. 18 | 19 | .directive('myDirective', function() { 20 | return { 21 | scope: true 22 | } 23 | }); 24 | 25 | 3) Your directives can also create new scopes that do not inherit from their parent scope via the `scope: {}` property. This means data accessible in parent scopes will not be accessible in the child scope, unless we explicitly pass it in through an attribute on the view: 26 | 27 | 28 |
29 | 30 | 31 | .directive('myIsolateDirective', function() { 32 | return { 33 | scope: { user: '=' } 34 | } 35 | }); 36 | 37 | In the new scope, we explicitly say we want to inherit the `user` object from `$rootScope`, but nothing else will inherit in the isolate scope. It will become modularized. 38 | 39 | 4) Your directives do not have to define a new scope. By default, they do not. We can also explicitly say we do not want to create a new scope (we want to use the parent scope) by setting the `scope: false` property: 40 | 41 | .directive('my-directive', function() { 42 | return { 43 | scope: false 44 | } 45 | }); -------------------------------------------------------------------------------- /Namespaced Routes.md: -------------------------------------------------------------------------------- 1 | # Namespaced Routes 2 | 3 | You want your users to have a products page, and your admin to have a special products page; you need an admin backend, and a good way to separate these concerns is via a namespace. 4 | 5 | If you know about modules, you already know about namespaces. To set up your namespaced routes: 6 | 7 | config/routes.rb: 8 | 9 | Routes::Application.routes.draw do 10 | namespace :admin do 11 | resources :products 12 | end 13 | 14 | resources :products 15 | 16 | root to: "products#index" 17 | end 18 | 19 | Now `rake routes` produces: 20 | 21 | admin_products GET /admin/products(.:format) admin/products#index 22 | POST /admin/products(.:format) admin/products#create 23 | new_admin_product GET /admin/products/new(.:format) admin/products#new 24 | edit_admin_product GET /admin/products/:id/edit(.:format) admin/products#edit 25 | admin_product GET /admin/products/:id(.:format) admin/products#show 26 | PUT /admin/products/:id(.:format) admin/products#update 27 | DELETE /admin/products/:id(.:format) admin/products#destroy 28 | products GET /products(.:format) products#index 29 | POST /products(.:format) products#create 30 | new_product GET /products/new(.:format) products#new 31 | edit_product GET /products/:id/edit(.:format) products#edit 32 | product GET /products/:id(.:format) products#show 33 | PUT /products/:id(.:format) products#update 34 | DELETE /products/:id(.:format) products#destroy 35 | root / products#index 36 | 37 | In your controllers folder, add an admin folder (for the admin namespace), and inside add the products_controller. Outside the admin namespace, you'll add another products_controller. 38 | 39 | Inside the admin products_controller, establish the namespace: 40 | 41 | module Admin 42 | class ProductsController < ApplicationController 43 | 44 | Your controller actions ... 45 | 46 | end 47 | end 48 | 49 | And in the views, you can establish the same schema, with a products folder under the top views folder, and another products folder under an admin folder. Each of those folders can have the standard `index.html.erb`, `show.html.erb`, etc. without bumping into one another. -------------------------------------------------------------------------------- /Setting Up RSpec.md: -------------------------------------------------------------------------------- 1 | # Setting Up RSpec 2 | 3 | This article describes the RSpec setup process in both Ruby and Rails. After setting up in whichever environment you'll be developing in, we recommend you check out [Writing Specs in RSpec](https://github.com/brettshollenberger/ruby_wiki/blob/master/Writing%20Specs%20in%20RSpec.md), and then move on to [RSpec Methods](https://github.com/brettshollenberger/ruby_wiki/blob/master/RSpec%20Methods.md). 4 | 5 | #### In Plain Ruby: 6 | 7 | * Conventionally, you'll establish the following file structure: 8 | 9 | > application_root 10 | - .rspec 11 | - Gemfile 12 | >> lib 13 | - app.rb 14 | >> spec 15 | - app_spec.rb 16 | 17 | * The .rspec folder can contain this setting to colorize the output in the traditional red/green style: 18 | 19 | --color 20 | 21 | * The Gemfile also only need include a single line: 22 | 23 | gem 'rspec' 24 | 25 | * In the app_spec.rb file, at the top of the document, make sure to include: 26 | 27 | require "rspec" 28 | require_relative "../lib/app" 29 | 30 | Where app is the name of the app.rb file. Now your spec file is linked to your app file, and ready to rock and roll. Make sure, if you haven't already got the [gem](https://github.com/brettshollenberger/ruby_wiki/blob/master/Gems.md) in the current [gemset](https://github.com/brettshollenberger/ruby_wiki/blob/master/Gemsets.md) that you run: 31 | 32 | bundle 33 | 34 | To download RSpec and get moving. 35 | 36 | #### In Rails 37 | 38 | * When generating a new Rails project, add the flag ``--skip-test-unit`` to supress creation of the test directory associated with the default Test::Unit framework. 39 | * In the Gemfile, add: 40 | 41 | group :development, :test do 42 | gem 'rspec-rails' 43 | end 44 | 45 | * The development mode RSpec files add RSpec-specific generators 46 | * Test mode includes files to run the tests 47 | * RSpec is a dependency of RSpec-Rails, so we don't need to include it. 48 | * Run this snippet to configure Rails to use RSpec in place of Test::Unit 49 | 50 | rails generate rspec:install 51 | 52 | * If the system complains about a lack of Javascript runtime (mine didn't), visit the execs page at GitHub for a list of possibilities (Hartl recommends Node). 53 | * Run bundle: 54 | 55 | bundle 56 | 57 | #### Retroactively Adding RSpec to a Rails App 58 | 59 | Use the `-s` flag to signal spec generation and set the `--migration` flag to `false` so you don't create a duplicate model. 60 | 61 | rails g model ModelName -s --migration=false 62 | -------------------------------------------------------------------------------- /Active Record Referential Integrity.md: -------------------------------------------------------------------------------- 1 | # Active Record Referential Integrity 2 | 3 | > "Garbage in, garbage out." 4 | -Ruby Buddha 5 | 6 | Data is the backbone of your application. Allow a user to enter bad data, and you've crippled yourself. 7 | 8 | Data can be validated in a number of locations: 9 | 10 | * _On the front-end_ aka the form the user enters the data into. If you've ever entered data on a page that told you that you'd entered incorrect information before you'd even submitted it, you've been validated on the front-end. Front-end validations were traditionally performed via Javascript, and can now also be performed using HTML5. Check here for [Front-End Validations](http://google.com) 11 | * _In the model_. When Rails receives the form from the user, and before it passes it to the database, it can perform its own validations. Validations in the model layer can be very robust. Check here for a list of [Active Record Model Validations](http://google.com) 12 | * _In the controller_. If you're coming from another object-oriented language, you may be tempted to perform validations in the controller. Ruby Buddha also advises to keep controllers skinny. Controller validations just ain't the Rails way. 13 | * _In the database_. Database validations are called _database constraints because they literally control what can and cannot be entered into the database. They should be your last line of defense against bad data. Check here for more on [Database Constraints](http://google.com). 14 | 15 | #### The Rails Way of Performing Validations 16 | Active Record (one of two modules that makes up the Rails model layer) claims that validation intelligence belongs in your models, not in the database. As such, features such as triggers or foreign key constraints, which push some of that intelligence back into the database, are not widely used. 17 | 18 | Like anything which operates at the application level, these cannot guarantee referential integrity and so some people augment them with foreign key constraints in the database. 19 | 20 | Although Active Record does not provide any tools for working directly with such features, the execute method can be used to execute arbitrary SQL. You could also use some plugin like foreigner which adds foreign key support to Active Record (including support for dumping foreign keys in db/schema.rb). 21 | 22 | Click here for the Big Bad Super List of [Active Record Model Validations](https://github.com/brettshollenberger/ruby_wiki/blob/master/Active%20Record%20Validations.md), which will get you started validating the Rails way. -------------------------------------------------------------------------------- /Git Merging.md: -------------------------------------------------------------------------------- 1 | # Git Merges 2 | 3 | #### Fast-Forward Merges 4 | 5 | You check out a topic branch, make a quick fix, and merge it back into master. All master has to do is to move its pointer ahead one commit, since there's no other branching history to consider. 6 | 7 | After merging, master will match the topic branch exactly, which can be removed using: 8 | 9 | git -d topicbranch 10 | 11 | ![Fast-Forward Merge](http://git-scm.com/figures/18333fig0312-tn.png) 12 | 13 | #### Recursive Merges 14 | 15 | Recursive merges occur when you have two histories on two separate branches: You checked out a topic branch, did some work, made some commits, and switched back to master, where you also did some work, and made other commits. When it comes time to merge the two together, Git must find the common ancestor of the two branches, the snapshot to merge into, and the snapshot to merge in, and merge the three together. 16 | 17 | Provided none of the work you did on the two branches overlapped, Git will have no problems. If, for instance, you had just X.rb on the ancestor, used the topic branch to create Y.rb, and the master to create Z.rb, you'll end up with a final merged project containing X.rb, Y.rb, and Z.rb with no conflicts. You're also ready to delete your topic branch now, since Git performs a `merge commit`--all changes have been successfully merged _and_ committed. 18 | 19 | ![The Three Amigos of the Recursive Merge](http://git-scm.com/figures/18333fig0316-tn.png) 20 | 21 | ![The Outcome](http://git-scm.com/figures/18333fig0317-tn.png) 22 | 23 | #### Merge Conflicts 24 | 25 | If you're not as lucky as in the example above, some of the work you did between the two branches conflicts with one another, and Git can't resolve the issue. 26 | 27 | It does have a few tools to help you out though. If you get the error: 28 | 29 | Auto-merging index.html 30 | CONFLICT (content): Merge conflict in x.rb 31 | 32 | You'll know you need to check out x.rb to resolve the issue. If you have a number of issues, you can always check which files still containing conflicts using `git status`. The conflicting files will appear as: 33 | 34 | # unmerged: x.rb 35 | 36 | The term `unmerged` refers to the fact that these files have not yet been successfully added to the merge. Since Git would have `merge commit`ted for us, we'll now have to manually add the changes ourselves when we're done: 37 | 38 | add x.rb 39 | 40 | To alert Git that the conflicts have been resolved. Then we can `commit`, and we'll have a nice, clean master branch again. 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /Composite Literal Syntax.md: -------------------------------------------------------------------------------- 1 | # Composite Literal Syntax 2 | 3 | Imagine you have a sheet of graph paper meant to hold your computer program. Each box can contain one simple item--a single character or number. How would you build a big program out of these tiny elements? 4 | 5 | An intuitive approach would be to begin grouping the small pieces. If we want arrays, we mark out a sequence of boxes, and begin filling in the values one box at a time. Since we want to remember the array concept--including its current length and total capacity, we create another simple structure: one cell points to the start of the array; one cell contains the numeric length; one cell contains the capacity. 6 | 7 | Strings can be represented in much the same way as arrays--except without the capacity. Why don't we want a capacity? First, we don't know how long the ultimate string will be. Strings have a willingness to change fairly often. Second, and related to the first point--we need an intelligent way to fill in our boxes in our sheet of graph paper. If we marked out a string, and then jumped down a few rows just to give the string some more breathing room--what happens when we run out of space? Do we start coming back and filling in the unfilled boxes? That's a sure-fire way to have technically enough squares to add some new values, but not enough contiguous squares to fill in the new array we want. 8 | 9 | Instead, we mark out a space for our string. This space will never change. If we want to append something new to the string, we'll copy the old one, plus the new one, and put the joined string at the end of our set of boxes. If we have no more need for the old string (maybe the new string has totally come to replace it), then we'll erase the old string from our sheet of paper, freeing up those old boxes. One important reason we do this is so that we can make other cheap references to our original string without fear of it changing out from under us. 10 | 11 | What happens, if for example, we have several slices of the original string lying around? We started with the string "hello world," and then made a slice to reference "hello" and one to reference "world." Then we changed "world" to "friend." Now our "world" slice refers to "friend." Whoops! That's not what we want at all. What we want is for our original string to be immutable. It will never change from under us. Instead, we make copies, and when nothing else refers to our original string anymore, we know that we're free to erase it. 12 | 13 | This is composite literal syntax in a nutshell--our ability to arrange and rearrange simple units into more complex structures that more closely resemble thought. -------------------------------------------------------------------------------- /API.md: -------------------------------------------------------------------------------- 1 | #API 2 | 3 | Application programming interfaces (APIs) can seem confusing--in a theoretical sense, we say they're a set of standards, like Morse code or the periodic table; in our day-to-day endeavors, we see a different type of thing: a RESTful web API might actually be a portal to perform CRUD operations on a dataset, and a keyboard or mouse might be conceived of as a primary interface to a type of program. What ties these concepts together? 4 | 5 | _An API is a means of describing or interacting with an abstract concept._ Language is our primary means to relate abstract concepts--we know what we mean when we say "dog" and "cat" and even when we say "love" or "hope;" the interface is a means of referring and also the transfer of reference itself--the spoken word or typed letter or Morse-encoded signal. 6 | 7 | > The tricky thing is that the way we describe abstract concepts may shape the way we view quote-unquote objective reality. 8 | 9 | In 2013 America, we have a word for every shade in the Crayola box. In the Homeric age, there were less than ten color words, and they were used quite differently--Homer describes the sky as bronze, honey as green, and the sea the color of a red wine. In some cultures, there are just two color words--one for "the warm color" and one for "the cool color"--or what we see as encompassing all of warm and cool color respectively. The real question is: do these cultures see in only two colors, while we perceive many more? Does our means of referring significantly shape our actual experience of "objective reality?" 10 | 11 | The pragmatic answer, of course, is yes. In the early days of the DOM, we had just a few objects to refer to--images and forms. Then Netscape and Internet Explorer devised competing worldviews on the organization of objects within a document, and DHTML became a dirty word--impossible to implement across browsers with different concepts regarding how the same thing worked. Finally, the W3C came along to introduce DOM Level 1, and restore some sanity in the world. But they conceived of the DOM API in the same way we conceive of our "World API"--the one filled with dogs and cats and love and hope--as a much larger interface: a way to refer to objects in any document in any markup language from any programming language in the world. 12 | 13 | These standards offer us a shared, implementation-agnostic convention through which to understand a concept, or they may be one implementation of the interface itself--a keyboard used to type the English language--a shared representation of the world. In this sense, the APIs we build are the most important things we work on, as they fundamentally shape the way we, and others, view development. -------------------------------------------------------------------------------- /Angular Initialization.md: -------------------------------------------------------------------------------- 1 | # Angular Initialization 2 | 3 | Angular automatically initializes under one of the following circumstances: 4 | 5 | * When the DOMContentLoaded event fires. This event fires when the browser has finished loading and parsing a document, excluding its dependencies, like stylesheets and images. 6 | * When the Angular source code on a page is evaluated if at that time `document.readyState` is set to `complete`. While a document is loading, its state will be `loading`; while it's loading dependencies, its state will be `interactive`; and when it's finished loading, it will reach `complete` state. 7 | 8 | Then Angular performs four actions during initialization: 9 | 10 | 1) Find the `ng-app` directive on the page. This directive might be on the `` element if we want Angular to manage the entire document, or on a `
` if we want it managing just a part of the page. 11 | 12 | 2) Load the module associated with the `ng-app` directive. Although Angular does not require you to use its module system, this is a great reason to do so: you can determine what will be loaded during initialization. Also, modules are essential for managing larger, complex apps, and Angular is intended to be a front-end solution for single-page applications, which are increasingly complex on the front-end, so it's a good practice to get used to. 13 | 14 | Generally, you'll have a root file called `app.js` (we store ours in `client/app/scripts` because we currently use the [Genesis Skeleton](http://genesis-skeleton.com) build for our MEAN apps), and in that file you'll create the app module: 15 | 16 | // Name the ng-app directive in the index.html file 17 | 18 | 19 | // Use the same module name in index.js 20 | angular 21 | .module('app', [dependencies]) 22 | .config([dependencies], callback() { 23 | }); 24 | 25 | 3) Create the application injector. $injector is a service provided by Angular that allows for instantiation, annotation, and retrieval of other registered services. Often injection is performed via the inline notation that's seen on the previous example, wherein the names of a function's dependencies are listed as strings, which $injector looks up and injects into the objects or functions: 26 | 27 | app.controller('CommentsController', ['$scope', 'Comment', 'FacebookService', function($scope, Comment, Facebook) { 28 | ... wonderful controller logic ... 29 | ]}); 30 | 31 | 4) Compile the DOM, treating the `ng-app` directive as the root of the compilation. In this way, you can use the `ng-app` directive to dictate that only a piece of your application should be visible to Angular, with the rest managed by Rails or some other framework. 32 | 33 | -------------------------------------------------------------------------------- /Rspec Before vs Let.md: -------------------------------------------------------------------------------- 1 | #RSpec before vs let 2 | 3 | In RSpec, there are two ways to DRY up tests (before and let) that share an intersecting purpose: to create variables that are common across tests. For common variable instantiation, the Ruby community prefers _let_, and while _before_ is often used to perform actions common across tests, the purpose of this article is to explore the differences between before and let for common variable creation in order to explain why let is preferred. 4 | 5 | #### before creates instance variables; let creates lazily-evaluated local variables 6 | 7 | Let variables don't exist until called into existence by the actual tests, so you won't waste time loading them for examples that don't use them. They're also memoized, so they're useful for encapsulating database objects, due to the cost of making a database request. 8 | 9 | let(:valid_user) { User.find_by_email(email) } # Let queries the database once, and then saves the valid_user object locally 10 | 11 | before { @valid_user = User.find_by_email(email) } # Before queries the database before each spec. 12 | 13 | Before statements are run _before each test_, and increase load times. When you are going to `visit root_path` before a number of tests anyway, a before statement makes sense: you'd be calling the visit method the same number of times and before DRYs up your tests. For variables, you end up using more processing power unnecessarily. 14 | 15 | #### instance variables default to nil 16 | 17 | Instance variables spring into existence (if they weren't previously defined) as _nil_. That means typos in before blocks can be nefarious, allowing certain types of tests to pass when they shouldn't. 18 | 19 | before(:each) do 20 | @user = User.find(username: "belleandsebastian") 21 | @user.logout 22 | end 23 | 24 | it "should log the user out" do 25 | expect(@usr).to be_nil 26 | end 27 | 28 | In this example, the actual test has a typo: 29 | 30 | expect(@usr).to be_nil 31 | 32 | Since @usr wasn't previously defined, the test will pass, but not because @user is logged out, but rather because @usr wasn't previously instantiated, and so _is nil_ by default. 33 | 34 | The same test using let would raise NameError because usr isn't defined. 35 | 36 | let(:user) { User.find(username: "belleandsebastian" } 37 | before { user.logout } 38 | 39 | it "should log the user out" do 40 | expect(usr).to be_nil 41 | end 42 | 43 | Here, the test fails, as we expected, and Ruby alerts us of our typo" 44 | 45 | NameError: undefined local variable or method 'usr' 46 | 47 | Notice we still utilized a before statement in this example, since we needed to call the logout method on user. Before statements have a purpose, but variable definition is better served by let. 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /Unix File Permissions.md: -------------------------------------------------------------------------------- 1 | # Unix File Permissions 2 | 3 | In general on Unix systems, we have the concepts of users & groups. Users are individual operators of the system, and groups are logic sets of users that share certain permissions (access to files and directories on the system). 4 | 5 | File permissions are set in triplets: 1) What the owner of the file can do with it, 2) What the owner group can do with the file, and 3) What everyone else (others) can do with the file. 6 | 7 | File permissions have three modes: 1) Read, 2) Write, and 3) Execute. 8 | 9 | File directories have the same three modes, with different meanings: 1) Read - view the contents of a directory, 2) Create or delete files within the directory (note: a user with directory permission can delete files they do not have specific file-wise write access to), and 3) Execute - `cd` into the directory. 10 | 11 | ## Viewing File Permissions 12 | To view the permissions of files: `$ ls -l ` 13 | 14 | | Owner user | Owner group | Others | 15 | | ------------------------- |:------------------:|:-------------------:| 16 | | -rwx | r-x | r-x | 17 | | read, write, execute | read, execute | read, execute | 18 | 19 | ## Updating File Permissions 20 | To update file permissions, use the `chmod` program: 21 | 22 | `chmod [options] mode file(s)` 23 | 24 | Updating modes: 25 | 26 | u - Owner user 27 | g - Owner group 28 | o - Others 29 | a - All (default) 30 | 31 | + - Set bits 32 | - - Clear bits 33 | 34 | r - Read bit 35 | w - Write bit 36 | x - Execute bit 37 | 38 | Examples: 39 | 40 | # set execute bit for owner 41 | chmod u+x some.file 42 | 43 | # set read bits for all 44 | chmod a+r some.file 45 | 46 | # alternately 47 | chmod +r some.file 48 | 49 | # set write bit for owner group 50 | chmod g+w some.file 51 | 52 | # clear write bit for others 53 | chmod o-w some.file 54 | 55 | # setting many bits at once for owner 56 | chmod u+rwx some.file 57 | 58 | ## Funny Numbers 59 | 60 | Often, you'll see permissions described using a numerical shorthand, such as 755: 61 | 62 | user rwx => 4 + 2 + 1 = 7 63 | group r-x => 4 + 1 = 5 64 | others r-x => 4 + 1 = 5 65 | 66 | ## Setting Default Modes 67 | 68 | Default modes can be set using `umask`. `umask` tends to be set in `/etc/profile` (loaded for all users), `/etc/.bashrc`, (also loaded for all users), or on a user-specific basis in that user's files (e.g. `~/.profile` or `~/.bashrc`). `umask` _masks_ file permissions (it is subtractive), so: 69 | 70 | # umask masks file permissions (is subtractive) 71 | umask 022 => (7 - 0) (7 - 2) (7 - 2) => 755 72 | umask 222 => (7 - 2) (7 - 2) (7 - 2) => 555 73 | 74 | By default, `umask` is set to `022`. 75 | 76 | 77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /Use SVG for Infinite Image Scalability.md: -------------------------------------------------------------------------------- 1 | # Why We Should be Using SVG 2 | 3 | I recently stumbled upon [Avdi Grimm's](https://twitter.com/avdi) awesome idea [PairProgramWith.Me](http://www.pairprogramwith.me). The site comes with a crisp, simple badge by [David Browning](http://twoguys.us), that's the perfect type of image to be an SVG: simple, computer-generated; it was very likely made in Illustrator anyway, so why does the site come with a .png version instead of an .svg? 4 | 5 | The likely answer is browser support. PNG's had full support since IE6 officially died (it did, right?), and the first SVG specification from the W3C became a recommendation in August 2011--kind of young as far as the web is concerned. PNG's been used fairly widely on the web lately, and for good reason--it supports a similar color range to .jpg as well as transparency (which .jpg doesn't, duh), and file sizes are usually smaller. Add in browser support, and you've got yourself a rather pragmatic option. 6 | 7 | But here's why I think .svg is the way to deploy image files as of 2013: 8 | 9 | 1) Vector is the format designers have traditionally chosen for print design. It's made to be scaled up--ready for it?--infinitely. We've already begun transitioning to responsive design as credo, and svg should be part of your design process. You don't know who will be viewing your image at what size on what screen when. And it doesn't cost you a thing to have a very largely displayed svg. Which leads us to: 10 | 11 | 2) It's tiny. A 300 x 300px png file will be smaller by an order of a KB or two, but an svg is an svg is an svg. SVG is just math: something computers are very good at doing. At any size, it's not only just as crisp, it's also just as expensive as it is at any other size. 12 | 13 | 3) Browser support. IE8 and down is a no go, so if that's your bread and butter, SVG is not the path for you. Marketshare on IE8 was still considerable as of April 2013--around 10%--but we're quickly headed for a world of widespread SVG acceptance. 14 | 15 | #### The #1 SVG Gotcha: 16 | 17 | When exporting your svg image, make sure you select the option "Convert to Outlines." Those familiar with the print world will implicitly understand this one: this option will ensure viewers see the typefaces you intended them to see. 18 | 19 | If you don't convert to outlines, some browsers (Firefox) will attempt to display the font using the user's system fonts. If the user doesn't have the typeface, the browser will fall back on something without your having a say in the matter. Converting to outlines will ask svg to convert the typeface to geometric shapes just like the rest of the image, thus preserving your image across browsers and providing a consistent experience. 20 | 21 | ![An svg version of Browning's awesome Pair with me button](http://brettshollenberger.herokuapp.com/assets/pair-original-colors.svg) -------------------------------------------------------------------------------- /Test Driven Angular.md: -------------------------------------------------------------------------------- 1 | # Angular Test Driven Development 2 | 3 | Test-driven development is an approach to building software where you write tests for features that don't yet exist, and then implement the feature so that it passes the tests. It's an assertive way to describe how your software is supposed to function, and serves as documentation for other developers. At Faculty Creative, we write software for clients, and at any given point in time our clients' needs are going to change--we know that--so it's important for me to document the features that I implement so my fellow devs know that when they add new features, or change a feature's implementation, that it still works as expected. 4 | 5 | For front-end development, we use the Angular.js, with Karma & Jasmine for unit tests and Protractor for integration tests. Integration tests describe the high-level functionality of a webpage; they allow us to assert what happens when a user fills in a form, clicks a button, or navigates to a specific page as an admin, user, or other role. Unit tests assert fine-grained functionality about the way a particular module, directive, or service works. We use an outside-in approach to software development, meaning we write integration tests first, then unit tests, and finally the code itself. While this approach requires a bit more overhead up front, it saves us time in the long run by allowing our developers to know that they haven't introduced new bugs, and allowing our devs that review pull requests to see that the software as a whole still functions as expected. 6 | 7 | The point of this post is to introduce you to the testing suites that we use in house, and to show you how to set the up to test your own code. First and foremost, let's take a look at the different tools that exist, and what they aim to do: 8 | 9 | #### Test Runners 10 | 11 | Test runners run your tests, usually from the command line. For unit tests, we use Karma, which is test-framework and assertion library agnostic. Karma lets you use Jasmine, Mocha, QUnit, or any other library you'd like to use to write the tests (although for other test libraries, you'll have to write your own adapter to get Karma to support it). Karma allows you to execute your tests in real browsers, locally during development, and on every save, so that you can be certain at all times that your code still functions as expected. 12 | 13 | Karma is a Node package, meaning you'll need to install Node first. From the command line: 14 | 15 | git clone git://github.com/ry/node.git 16 | cd node 17 | ./configure 18 | make 19 | sudo make install 20 | 21 | Next you'll need npm, Node's package manager. To get it from the command line: 22 | 23 | curl https://npmjs.org/install.sh | sh 24 | 25 | Now you can install Node packages, like Karma: 26 | 27 | npm install -g karma 28 | 29 | The `g` flag in the script above will install Karma globally. 30 | 31 | -------------------------------------------------------------------------------- /Barewords.md: -------------------------------------------------------------------------------- 1 | # Barewords 2 | 3 | In Ruby, there are lots of fancy ways of referring to data--constants, global variables, local variables, instance variables, class methods, instance methods; the list goes on. Most of these modes of reference are decorated-- `$global_var` or `CONSTANT`--for example. That means that if we change the _way_ we refer to data, we have to change each reference to that data, or we'll introduce bugs. 4 | 5 | _Barewords_ on the other hand, are undecorated data references--`local_var` and `method_call`--for instance. Their lack of decoration adds an inherent flexibility; if we decide to change their implementation later, we can implement them as another form of bareword and save ourselves from bricking our implementation. Barewords also happen to be much more readable. 6 | 7 | #### Types of Barewords 8 | 9 | In Ruby, there are three types that are called as barewords: 10 | 11 | * Local variables 12 | 13 | 14 | def salutation 15 | greeting = "Hello " 16 | puts greeting + "Brett" 17 | end 18 | 19 | 20 | * Method parameters 21 | 22 | def salutation(greeting) 23 | puts greeting + " Brett" 24 | end 25 | 26 | salutation("Hello") 27 | 28 | 29 | * Parameterless methods 30 | 31 | def greeting; "Hello "; end 32 | 33 | def salutation(greeting=greeting) 34 | puts greeting + "Brett" 35 | end 36 | 37 | salutation 38 | >> "Hello Brett" 39 | 40 | With these three types, we can and should replace nearly any other implementation, as long as we know a bit more about how Ruby works. 41 | 42 | For instance, we know that methods defined on the _main_ object have the magical quality of being added as `private` methods to all other objects, and therefore we can replace global variables with methods defined on the main object: 43 | 44 | $global_var = "Accessible anywhere, but decorated." # becomes: 45 | def global_var; "Accessible anywhere, and undecorated."; end 46 | 47 | #### Gotchas 48 | 49 | The primary gotcha I see with barewords is the propensity for collisions. Consider: 50 | 51 | def greeting; "Hello "; end 52 | 53 | def salutation(greeting) 54 | greeting = "Hola " 55 | puts greeting + "Brett" 56 | end 57 | 58 | salutation "Sup " 59 | 60 | Which of the forms of greeting gets called in the implementation above? Of course it's the local variable; in each case, it's easy to see which will attain precedence by proximity or order of definition. Just be aware that not only can these types of collisions occur, they can also make it hard to root out the definition of a particular bareword for users new to your codebase. In all, barewords will save your company time and money by keeping you from having to dig up the origins of bugs introduced by changing implementations, and I'd still highly recommend using them. Barewords allow your methods to concern themselves with how they work, not where they get their data. 61 | 62 | 63 | -------------------------------------------------------------------------------- /Patterns of Enterprise Architecture.md: -------------------------------------------------------------------------------- 1 | # Patterns of Enterprise Architecture 2 | 3 | #### Architecture 4 | 5 | 1) Is defined differently across the software space 6 | 2) Often refers to the shared understanding expert developers have about a project, and the way its major components interact 7 | 3) Refers, specifically to the things that are difficult to change 8 | 9 | > If it's easier to change than you thought, it isn't architecture 10 | 11 | #### Enterprise Applications 12 | 13 | Enterprise applications tend to deal with: 14 | 15 | 1) Complex, persisted data 16 | 2) Business logic (logic related to the enterprise) 17 | 18 | The nature of enterprise applications causes several distinct architectural problems to face: 19 | 20 | 1) Over time, many different applications and types of users will access the same data 21 | 2) Over time, the systems that access data will need to change 22 | 3) Over time, the data schemas will be forced to change 23 | 4) In distributed systems, many concurrent users may access and interact with data at the same time, which can cause inconsistencies 24 | 5) Different users require different views and levels of detail about information 25 | 6) We have to integrate our systems with other systems in the enterprise 26 | 7) Integration efforts are often incomplete or messy 27 | 8) Different users perceive the model in subtly different ways, or talk about the models in different ways in their departments 28 | 9) Various systems require data to be in various formats 29 | 10) Business logic is often illogical, but difficult to change without significant political effort 30 | 11) Business logic can contradict itself 31 | 32 | #### Organizing Domain Logic: 33 | 34 | Fowler presents three methods for organizing domain logic: 35 | 36 | 1) Transaction script - Procedural, simple business transactions. Can share code via subroutines, but often results in duplication and exponentially increased complexity as domain logic complexity increases. Suffers from a lack of discernible organization. 37 | 2) Domain model - Organization of the nouns within the domain into classes that interact with a persistence layer, often via Row Data Gateway or Table Data Gateway. Though the initial cost in understanding domain model is the highest of the three, it offers the simplest, most linear scalability as domain logic complexity increases (and it always will). 38 | 3) Table module - Where domain model has one instance per db record, table module has one instance (the table). This works with a record set, and formalizes some bits of the transaction script model, while still primarily using procedural code. 39 | 40 | The basic advice of Fowler is that if a team knows domain model well, it's usually the best choice. If working in an environment where a lot of tools are geared towards working with record sets, like .NET, then table module can be a good choice, but otherwise it doesn't offer benefits over domain model. -------------------------------------------------------------------------------- /Angular Models.md: -------------------------------------------------------------------------------- 1 | # Angular Services as Access to Models 2 | 3 | In Angular.js, the concept of a model is not well-described. That's because--seriously--there aren't models in Angular, even if the powers that be say there are. Traditionally, we think of a model as a representation of a type of data and a means of interacting with a database to persist that data. That means the model must live on the server, and Angular lives on the client. 4 | 5 | Fine, but pedantry aside, interacting with our data in Angular is also kind of a pain for a "framework" that describes the model as the ultimate source of truth. In Angular, we could easily setup a "model" that persists nowhere and is defined in a single place: 6 | 7 | 8 | {{data}} 9 | 10 | In the example above, anything typed into the input becomes bound to the "data" model, and updated in the binding below (since Angular's two-way binding automatically represents changes to the model in the view, and vice-versa. And those things are all super rad, but this "model" is bound to its scope, and _not_ to anything global, since Angular's allergic to things that should be global, and I count data and services among those things. 11 | 12 | For instance, we can see how in two different scopes (two separate controllers and `
`s) we already lose the wonderful power of the two-way binding--the "data" model only refers to the "model" within its own scope: 13 | 14 |
15 | 16 | {{data}} 17 |
18 | 19 |
20 | 21 | {{data}} 22 |
23 | 24 | These scopes don't share "data," which should be the canonical representation of data, which should end up being wildly confusing in an app of any respectable size. So how can we share data among controllers? 25 | 26 | #### Useful Angular "Models" 27 | 28 | Again, I'm using the term "model" here loosely because a service is not a model, but _services_ are the accepted means in the Angular community of hooking up data among various controllers. A service is a factory that returns a singleton object containing the properties of a particular model. Since that's the case, we can share this singleton among our controllers through the magic of Angular's dependency injection, and cause these two scopes to update the same "data" model: 29 | 30 | myApp.factory("Data", function() { 31 | return { 32 | message: "Service data coming atcha!" 33 | }; 34 | }); 35 | 36 | function FirstScope($scope, Data) { 37 | $scope.data = Data; 38 | }; 39 | 40 | This method is better, but still kind of crummy--why should we have to inject the canonical service into every controller? We should be creating an ApplicationController a la Rails, which the other controllers inherit from, and injecting the dependencies there so we don't have many injections to perform with every new service. 41 | 42 | -------------------------------------------------------------------------------- /Array Methods.md: -------------------------------------------------------------------------------- 1 | # Array Methods 2 | 3 | #### Array.at(index) -- Returns value or nil if index DNE 4 | 5 | a = [1, 2, 3] 6 | a.at(0) 7 | >> 1 8 | 9 | a.at(100) 10 | >> nil 11 | 12 | #### Array.fetch(index) -- Returns value or IndexError if index DNE 13 | 14 | a.fetch(100) 15 | >> IndexError 16 | 17 | #### Array.first 18 | 19 | a.first 20 | >> 1 21 | 22 | #### Array.last 23 | 24 | a.last 25 | >> 3 26 | 27 | #### Array.take(num) 28 | 29 | arr = (1..6).to_a 30 | >> [1, 2, 3, 4, 5, 6] 31 | 32 | arr.take(3) 33 | >> [1, 2, 3] 34 | 35 | arr 36 | >> [1, 2, 3, 4, 5, 6] # Take is non-destructive 37 | 38 | #### Array.drop(num) 39 | 40 | arr.drop(3) 41 | >> [4, 5, 6] # Drop is also non-destructive 42 | 43 | #### Array.count 44 | 45 | arr.count 46 | >> 6 47 | 48 | #### Array.length 49 | 50 | arr.length 51 | >> 6 52 | 53 | #### Array.empty? 54 | 55 | arr.empty? 56 | >> false 57 | 58 | b = [] 59 | b.empty? 60 | >> true 61 | 62 | #### Array.include? 63 | 64 | arr.include?(99) 65 | >> true 66 | 67 | arr.include?(101) 68 | >> false 69 | 70 | b = ['strawberry'] 71 | b.include?('strawberry') 72 | >> true 73 | 74 | #### Array.push(value) -- Add value at the end of the array 75 | 76 | c = [1, 2, 3] 77 | c.push(4) 78 | >> [1, 2, 3, 4] 79 | 80 | #### Array.pop -- Removes and returns the last element in an array (destructive) 81 | 82 | c.pop 83 | >> 4 84 | c 85 | >> [1, 2, 3] 86 | 87 | #### Array.unshift(value) -- Add value at the beginning of the array 88 | 89 | c.unshift(0) 90 | >> [0, 1, 2, 3] 91 | 92 | #### Array.shift(value) -- Remove and return the first item (destructive) 93 | 94 | c.shift 95 | >> [1, 2, 3] 96 | 97 | #### Array.insert(index, value) 98 | 99 | c.insert(1, 'apple') 100 | >> [1, 'apple', 2, 3] 101 | 102 | #### Array.delete_at(index) 103 | 104 | c.delete_at(1) 105 | >> [1, 2, 3] 106 | 107 | #### Array.delete(value) 108 | 109 | c.delete(1) 110 | >> [2, 3] 111 | 112 | #### Array.compact -- Returns an array without nil values; not in place 113 | 114 | arr = ['a', 1, 'b', 2, nil, nil, 3, nil, 'happy'] 115 | arr.compact 116 | >> ['a', 1, 'b', 2, 3, 'happy'] 117 | arr 118 | >> ['a', 1, 'b', 2, nil, nil, 3, nil, 'happy'] # Compact is not performed in-place 119 | 120 | #### Exclamation point performs method in-place 121 | 122 | arr.compact! 123 | >> ['a', 1, 'b', 2, 3, 'happy'] 124 | arr 125 | >> ['a', 1, 'b', 2, 3, 'happy'] 126 | 127 | #### To remove duplicates in an array, there's the non-destructive Array.uniq and the destructive Array.uniq! 128 | 129 | a = [1, 1, 2, 3, 3] 130 | a.uniq # Modification not in-place 131 | >> [1, 2, 3] 132 | a 133 | >> [1, 1, 2, 3, 3] 134 | a.uniq! # Performs modification in-place 135 | >> [1, 2, 3] 136 | --------------------------------------------------------------------------------