Skip to content

Instantly share code, notes, and snippets.

@Jlawlzz
Last active July 17, 2016 23:59
Show Gist options
  • Save Jlawlzz/70ed4e093de334294cc5fbeb8f0b24ef to your computer and use it in GitHub Desktop.
Save Jlawlzz/70ed4e093de334294cc5fbeb8f0b24ef to your computer and use it in GitHub Desktop.

#Memoization

###What is it? At its most basic level memoization involves storing a value to prevent unnecessary work by identical calls in the future.

###Use:

  1. Memoization can be helpful when making duplicate database calls for static data. (like current_user)
- Example 1: 

           def pokemon_allegance
             @user_team ||= Team.find(current_user.team_id)
           end
           
           (team would be better represented with a User => Team association, I am using the above implementation to illustrate a clear database call)
           
           
- Example 2: If 'current_user.team' evaluates to 'nil' or 'false', the method will execute 'current_user.team' every time it is called again rendering '||=' useless.   This is fixed by using a less elegant but more thorough implementation.
            
            def pokemon_allegance
              return @user_team if_defined?(@user_team)
              @user_team = current_user.team
            end

            The 'if_defined?' method checks to see if its argument simply exists. If @user_team is equal to nil or false, 'if_defined?' still returns true, it will only allow the method to execute to completion if @user_team is undefined.
  1. Memoization is useful when you find yourself making duplicate expensive calculations or api calls.
- Example: API call
            
            def suggested_pokemon
              @pokemon ||= PokemonService.find_fav_pokemon(current_user.persality_profile)
            end 

            The same 'if_defined?' pattern described in the previous example can be applied here.
  1. A hashing system can be used in certain instances when variables representing more dynamic data can benefit from memoization.
- Example:  

            @fibbonachi_results = {}
            
            def fibbonachi_sequence(number)
              return @fibbonachi_results[number] unless @fibbonachi_results[number].nil?
              
              @fibbonachi_results[number] = calculate_fibbonachi(number) 
            end
            
            Because the fibbonachi calculation can be expensive and will not change with duplicate input, hashing the results can decrease response time and workload considerably.

#Cookies Vs Session Vs Local Storage

  1. Cookies:
- Data held by the client which holds information regarding to user preferences, web app state, and authentication.
- Client holds onto this information until the user decides to manually clear them. (persists even after browser is exited)
  1. Session:
- Data saved for the duration of a users current browsing session.
- Information persists in temporary memory until user closes the browser.
- Can be used for things like authorization ('session[user_id]'), shopping carts which are not intended to persist, really anything that a website needs to remember as a user navigates through an application.
  1. Local:
- Local storage is fundamentally different from the previous two examples in that it is stored and can only be read on the client side.
- Local storage allows you to save up to 5mb of data per site, much larger than the ~4k bytes of storage cookies allow.
- Has no expiration date. Can be cleared through client side Javascript or by manually resetting through a browsers preferences.
- Great for storing persistent data only the client needs to know about like what level you are on in a local javascript game, or your progress through a playlist on 8tracks.

###When working with Subdomains:

  • Without a 'domain' value saved in your 'Set Cookie' header, cookie data would not be preserved between 'www.8tracks.com' and 'www.8tracks.com/blog'. This would destroy data persistence within a website for the user.

#Polymorphism

###What is it?

  • "The use of a single interface on entities of different types."
  • In Ruby, this means we can interact with different objects (or classes) using the same interface (or methods), and achieve different results.

###Use:

  • Example 1: Inheritance

          class Animal
          
            def move
              puts 'the animal moved forward'
            end
            
            def sleep
              puts 'the animal went to sleep'
            end
          
          end
          
          class Dog < Animal
          
            def move
              puts 'the dog moved forward'
            end
            
          end
          
          class Snake < Animal
          
            def move
              puts 'the snake slithered forward'
            end
            
          end
          
          animal = Animal.new
          dog = Dog.new
          snake = Snake.new
          
          animal.sleep 
          'the animal went to sleep'
          dog.sleep
          'the animal went to sleep'
          snake.sleep
          'the animal went to sleep'
          
          When all three of these methods are called, they all output "the animal fell asleep", this is simply inheritance.
          
          animal.move
          'the animal moved forward'
          dog.move
          'the dog moved forward'
          snake.move
          'the snake slithered forward'
    

    When these methods are called they output three different things depending on which class is called. Although 'dog' and 'snake' inherent 'move' from 'animal', when 'move' is called the inherited 'animal.move' is ditched for the current classes definition. Polymorphism through Inheritance can be useful to more easily adhere to SRP (instead of a single 'Animal' class that takes an argument for the 'move' method to achieve variation, we can separate into three different classes.)

  • Example 2: Duck Typing

          class Dog
          
            def speak
              puts 'the dog barked'
            end
            
          end
          
          class Cat
          
            def speak
              puts 'the cat meowed'
            end
            
          end
          
          def make_sound(animal)
            animal.speak
          end
          
          dog = Dog.new
          cat = Cat.new
          
          make_sound(dog)
          'the dog barked'
          
          make_sound(cat)
          'the cat meowed'
    

    The 'make_sound' method here is polymorphic due to its ability to intake different types of objects without issue as long as the 'speak' method can be called on it. Duck Typing can be useful as a kind of type checking; but rather than checking that the argument passed through is of a certain type, duck typing only cares that the object can be interacted with in a consistent way.

#Rack Middleware

Rack provides a standardized Ruby interface for interaction with a webserver. Rack is incredibly simple on its own as it simply dictates how to take a request, and return a response. What makes it powerful is Racks modularity.

'ActionController' relies heavily on Rack Middleware, which can be customized using 'config.middleware...' in 'application.rb' or 'environments/.rb' if you wish to customize different middleware stacks for specific environments.

There are a few middleware modules that can help make routing faster:

  • 'ActionDispatch::Static' serves static file requests straight from the public directory.
  • 'Rack::ConditionalGet' returns an empty body with a '304 Not Modified' status if page has not been changed.
  • A Rack module called 'Metal' is the suggested method for handling simple dynamic requests as quickly as possible. 'Metal' or 'ActionController::Metal' is essentially a bare bones version of 'ActionController::Base'. Metal is used commonly with API's to improve response time (controller would inherit from ActionController::Metal, rather than 'ActionController::Base'). If additional bypassed functionality is needed in a 'Metal' controller, it can be inserted via 'include'.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment