Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save e-jambon/4dc7817e3b3d12e022c59a9f78798188 to your computer and use it in GitHub Desktop.
Save e-jambon/4dc7817e3b3d12e022c59a9f78798188 to your computer and use it in GitHub Desktop.

Revisions

  1. @venkatch789 venkatch789 revised this gist Jul 24, 2015. 1 changed file with 5 additions and 1 deletion.
    6 changes: 5 additions & 1 deletion gistfile1.md
    Original file line number Diff line number Diff line change
    @@ -360,4 +360,8 @@ To list all your rake tasks,

    Or if specific tasks,

    `$ rake -T | grep my_namespace`
    `$ rake -T | grep my_namespace`

    #### Explain Single Table Inheritance (STI) in Ruby?

    #### Explain Polymorphic Associations in Rails? And discuss what is the difference between STI and Polymorphic associations?
  2. @venkatch789 venkatch789 revised this gist Jul 24, 2015. 1 changed file with 2 additions and 0 deletions.
    2 changes: 2 additions & 0 deletions gistfile1.md
    Original file line number Diff line number Diff line change
    @@ -328,6 +328,8 @@ It is somewhat difficult to write about the weaknesses and constraints of Ruby o

    #### How would you create a rake task?

    *Rake* is Ruby make, a software task management tool, like *Make* utility in Unix systems.

    There are several ways to create a rake task.

    1. Create it from scratch
  3. @venkatch789 venkatch789 revised this gist Jul 24, 2015. 1 changed file with 4 additions and 4 deletions.
    8 changes: 4 additions & 4 deletions gistfile1.md
    Original file line number Diff line number Diff line change
    @@ -18,7 +18,7 @@ The flow of our example payment system is,

    If we want to implement this payment algorithm, it would look like,

    ```
    ```ruby
    class StripePayment
    def initialize card, amount
    @api_key = ENV['STRIPE_API_KEY']
    @@ -61,7 +61,7 @@ Well, we will think to add a new class and which defines the same flow. And what

    So, here comes the idea of *Template Method* pattern.

    ```
    ```ruby
    class BasePayment
    def initialize card, amount
    @card = card
    @@ -82,7 +82,7 @@ class BasePayment
    end
    ```

    ```
    ```ruby
    class StripePayment < BasePayment
    def authenticate_merchant
    begin
    @@ -107,7 +107,7 @@ class StripePayment < BasePayment
    end
    ```

    ```
    ```ruby
    class PaypalPayment < BasePayment
    def authenticate_merchant
    begin
  4. @venkatch789 venkatch789 revised this gist Jul 24, 2015. 1 changed file with 169 additions and 1 deletion.
    170 changes: 169 additions & 1 deletion gistfile1.md
    Original file line number Diff line number Diff line change
    @@ -190,4 +190,172 @@ def proc_test
    end
    proc_test # Calling this method will print nothing (i.e the flow control terminates within the Proc block only.)
    ```
    PS: *Both proc and lambda are the methods defined in the Kernal module*
    PS: *Both proc and lambda are the methods defined in the Kernal module*

    #### What is SQL injection?
    SQL injection is a `code injection` technique, used to attack data-driven applications, in which malicious SQL statements inserted into the entry field for execution.

    #### What is `splat` operator in Ruby?

    #### class_eval, instance_eval and module_eval

    *Ruby's most fame is its dynamic capabilities.*

    **class_eval and module_eval**
    These two methods grant you access to the existing class and module definition.

    ```ruby
    Dog.class_eval do
    def bark
    puts "huf huf..."
    end
    end
    ```
    ..is same as,

    ```ruby
    class Dog
    def bark
    puts "huf huf..."
    end
    end
    ```

    What's the difference?

    Well, using these methods we add methods to the exsting classes or modules at runtime.

    If our class called Dog is not defined before we use class_eval, we would see an error `NameError: uninitialized constant Dog`

    Perfect example for `class_eval` is implementation of `attr_accessor` in Rails.

    ```ruby
    Object.class_eval do
    class << self
    def attribute_accessor( *attribute_names )
    attribute_names.each do |attr_name|
    class_eval %Q?
    def #{attr_name}
    @#{attr_name}
    end
    def #{attr_name}=( new_value )
    @#{attr_name} = new_value
    end
    ?
    end
    end
    end
    end

    class Dog
    attribute_accessor :name
    end

    dog = Dog.new
    dog.name = "MyDog"

    puts dog.name
    ```

    - The module_eval method is just an alias to class_eval so you can use them both for classes and modules.

    **instance_eval**

    The `instance_eval` just works like `class_eval` but adds the behaviour to the particular object where it was called.
    That means the code added via `class_eval` works as it was added to the the class body. That is every object of class is permitted to access this behaviour. But the code added via `instance_eval` would be accessed to only that particular object.

    Let's see an example how it works,

    ```ruby
    class Dog
    attribute_accessor :name
    end

    dog = Dog.new
    dog.name = 'Fido'

    dog.instance_eval do
    #here I am defining a bark method only for this “dog” instance and not for the Dog class
    def bark
    puts 'Huf! Huf! Huf!'
    end

    end

    other_dog = Dog.new
    other_dog.name = 'Dido'

    puts dog.name
    puts other_dog.name

    dog.bark
    other_dog.bark #this line will raise a NoMethodError as there’s no “bark” method
    #at this other_dog object
    ```

    Lets' wrap it... No..no. wait! There is one more interesting point to be discuss,

    We know every class is an object in Ruby, so can I use `instance_eval` on the classes?

    Yes, we can use. And the methods defined in this way will be available as class methods to that class. That's interesting, right?

    Let's see an example,

    ```ruby
    Object.instance_eval do
    def attribute_accessor( *attribute_names )
    attribute_names.each do |attribute_name|
    class_eval %Q?
    def #{attribute_name}
    @#{attribute_name}
    end
    def #{attribute_name}=( new_value )
    @#{attribute_name} = new_value
    end
    ?
    end
    end
    end
    ```

    #### What are the limitations of Ruby on Rails?
    It is somewhat difficult to write about the weaknesses and constraints of Ruby on Rails when you actually are a Ruby on Rails developer

    - Ruby is slow, because of it is interpreted language.
    - Ruby on Rails development is community driven: there is no formal institution that would take the responsibility for the changes introduced to the framework.
    - Constant, rapid changes of the framework is also one type of limitation


    #### How would you create a rake task?

    There are several ways to create a rake task.

    1. Create it from scratch
    2. Copy-paste code from another ready rake task and change code to required.
    3. Use task generator

    Using generator,

    `$ rails g task my_namespace my_task1 my_task2`

    It will generate scaffold for our new rake task: >lib/tasks/my_namespace.rake

    ```ruby
    namespace :my_namespace do
    desc "TODO"
    task :my_task1 => :environment do
    end

    desc "TODO"
    task :my_task2 => :environment do
    end
    end
    ```

    To list all your rake tasks,

    `$ rake -T`

    Or if specific tasks,

    `$ rake -T | grep my_namespace`
  5. @venkatch789 venkatch789 revised this gist Jul 17, 2015. 1 changed file with 2 additions and 6 deletions.
    8 changes: 2 additions & 6 deletions gistfile1.md
    Original file line number Diff line number Diff line change
    @@ -144,7 +144,7 @@ end

    #### Blocks in Ruby

    *What are the differences between procs and lambdas?*
    **What are the differences between procs and lambdas?**

    Before getting into the differences, they are very similar and both are Proc objects.
    ```ruby
    @@ -190,8 +190,4 @@ def proc_test
    end
    proc_test # Calling this method will print nothing (i.e the flow control terminates within the Proc block only.)
    ```
    PS: *Both proc and lambda are the methods defined in the Kernal module*


    #### What is SQL injection?
    SQL injection is a `code injection` technique, used to attack data-driven applications, in which malicious SQL statements inserted into the entry field for execution.
    PS: *Both proc and lambda are the methods defined in the Kernal module*
  6. @venkatch789 venkatch789 revised this gist Jul 17, 2015. 1 changed file with 2 additions and 1 deletion.
    3 changes: 2 additions & 1 deletion gistfile1.md
    Original file line number Diff line number Diff line change
    @@ -141,9 +141,10 @@ end
    **Factory pattern**



    #### Blocks in Ruby

    #### What are the differences between procs and lambdas?
    *What are the differences between procs and lambdas?*

    Before getting into the differences, they are very similar and both are Proc objects.
    ```ruby
  7. @venkatch789 venkatch789 revised this gist Jul 17, 2015. 1 changed file with 56 additions and 1 deletion.
    57 changes: 56 additions & 1 deletion gistfile1.md
    Original file line number Diff line number Diff line change
    @@ -138,4 +138,59 @@ end

    **Decorator pattern**

    **Factory pattern**
    **Factory pattern**


    #### Blocks in Ruby

    #### What are the differences between procs and lambdas?

    Before getting into the differences, they are very similar and both are Proc objects.
    ```ruby
    proc = Proc.new { puts "Hello world" }
    lam = lambda { puts "Hello World" }

    proc.class # returns 'Proc'
    lam.class # returns 'Proc'
    ```
    And the differences are,

    + Lambda is very strict about the no.of arguments passed. It throws exception when incorrect arguments. But Proc does not complain abut the no.of arguments passed, it just returns *nil*.

    ```ruby
    lam = lambda { |x| puts x } # Creates a lambda that takes one argument and prints it
    lam.call(2) # It executes and prints 2
    lam.call # ArgumentError: Wrong number of arguments (0 for 1)
    lam.call(2,3) # ArgumentError: Wrong number of arguments (2 for 1)
    ```

    ```ruby
    proc = Proc.new { |x| puts x } # Creates a lambda that takes one argument and prints it
    proc.call(2) # It executes and prints 2
    proc.call # Returns nil
    proc.call(1,2,3) # It executes and prints 1. And it forgets about the extra arguments
    ```

    + Lambdas and Procs treat the `return` statement differently.
    If there is a return statement mentioned in the lambda, it continues to execute the rest of the code. But in Proc, the return statement will return the result for entire method.
    ```ruby
    def lamda_test
    lam = lambda { return }
    lam.call
    puts "Hello world!"
    end
    lamda_test # Calling this method will print "Hello world!" (i.e the flow control continues to execute after the lambda block also)
    ```
    ```ruby
    def proc_test
    proc = Proc.new { return }
    proc.call
    puts "Hello world!"
    end
    proc_test # Calling this method will print nothing (i.e the flow control terminates within the Proc block only.)
    ```
    PS: *Both proc and lambda are the methods defined in the Kernal module*


    #### What is SQL injection?
    SQL injection is a `code injection` technique, used to attack data-driven applications, in which malicious SQL statements inserted into the entry field for execution.
  8. @venkatch789 venkatch789 revised this gist Jul 17, 2015. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion gistfile1.md
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,4 @@
    #### Ruy Design patterns
    #### Design patterns (in Ruby)

    Design patterns are just tools that help us constructing a software.

  9. @venkatch789 venkatch789 revised this gist Jul 17, 2015. 1 changed file with 9 additions and 1 deletion.
    10 changes: 9 additions & 1 deletion gistfile1.md
    Original file line number Diff line number Diff line change
    @@ -130,4 +130,12 @@ class PaypalPayment < BasePayment
    end
    end
    end
    ```
    ```

    **Singleton pattern**

    **Observer pattern**

    **Decorator pattern**

    **Factory pattern**
  10. @venkatch789 venkatch789 revised this gist Jul 17, 2015. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion gistfile1.md
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,6 @@
    #### Ruy Design patterns

    * Design patterns are just tools that help us constructing a software.
    Design patterns are just tools that help us constructing a software.

    **Template Method pattern**

  11. @venkatch789 venkatch789 revised this gist Jul 17, 2015. 1 changed file with 2 additions and 1 deletion.
    3 changes: 2 additions & 1 deletion gistfile1.md
    Original file line number Diff line number Diff line change
    @@ -2,7 +2,8 @@

    * Design patterns are just tools that help us constructing a software.

    ** Template Method pattern **
    **Template Method pattern**

    In the *Template Method* pattern, we create a *skeletal class* and it is basis for various *subclasses* or *concrete classes*. Within in the skeletal class, there are abstract methods, which in turn, will be overridden by the methods of subclasses.

    Let's take an example of **simple payment system**,
  12. @venkatch789 venkatch789 revised this gist Jul 17, 2015. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion gistfile1.md
    Original file line number Diff line number Diff line change
    @@ -2,7 +2,7 @@

    * Design patterns are just tools that help us constructing a software.

    ** Template Method pattern
    ** Template Method pattern **
    In the *Template Method* pattern, we create a *skeletal class* and it is basis for various *subclasses* or *concrete classes*. Within in the skeletal class, there are abstract methods, which in turn, will be overridden by the methods of subclasses.

    Let's take an example of **simple payment system**,
  13. @venkatch789 venkatch789 revised this gist Jul 17, 2015. 1 changed file with 82 additions and 0 deletions.
    82 changes: 82 additions & 0 deletions gistfile1.md
    Original file line number Diff line number Diff line change
    @@ -10,10 +10,13 @@ Let's take an example of **simple payment system**,
    Usually, the payment process has the same flow regardless of the provider we use.

    The flow of our example payment system is,

    1. Authenticate the merchant (our application) with the provider
    2. Send the User's card data with the amount of order
    3. Receive confirmation or error from the provider

    If we want to implement this payment algorithm, it would look like,

    ```
    class StripePayment
    def initialize card, amount
    @@ -47,4 +50,83 @@ class StripePayment
    end
    end
    end
    ```

    So this looks all fine. We can instantiate a new StripePayment object, pass the card object and the amount of the order as parameters in the initializer and call the process_payment! method on the object to execute the payment. For a successful payment, we need the Merchant (our web application) to successfully authenticate with the payment provider (Stripe) and then the credit card to be charged the total of the order. If any of these two fail, the payment wont be processed.

    What about PayPal payment?

    Well, we will think to add a new class and which defines the same flow. And what if we would like to add another payment options like credit card payment, or some other.

    So, here comes the idea of *Template Method* pattern.

    ```
    class BasePayment
    def initialize card, amount
    @card = card
    @amount = amount
    end
    def process_payment!
    authenticate_merchant && make_payment
    end
    def authenticate_merchant
    raise NotImplementedError.new "authenticate_merchant"
    end
    def make_payment
    raise NotImplementedError.new "make_payment"
    end
    end
    ```

    ```
    class StripePayment < BasePayment
    def authenticate_merchant
    begin
    return true if Stripe::Merchant.authenticate ENV['STRIPE_API_KEY']
    rescue Stripe::MerchantError => e
    Rails.logger.error "Cannot establish connection between Merchant and Provider."
    return false
    rescue Stripe::ProviderUnreachable => e
    Rails.logger.error "Provider unreachable."
    return false
    end
    end
    def make_payment
    begin
    return true if Stripe::Payment.process! ENV['STRIPE_API_KEY'], @card, @amount
    rescue Stripe::PaymentUnprocessable => e
    Rails.logger.error "Payment unprocessable, try again."
    return false
    end
    end
    end
    ```

    ```
    class PaypalPayment < BasePayment
    def authenticate_merchant
    begin
    return true if Paypal::Account.authenticate ENV['PAYPAL_API_KEY']
    rescue Paypal::NotAuthenticated => e
    Rails.logger.error "Cannot establish connection between Merchant and Provider."
    return false
    rescue Paypal::NotFound => e
    Rails.logger.error "Provider unreachable."
    return false
    end
    end
    def make_payment
    begin
    return true if Paypal::Payment.create! ENV['PAYPAL_API_KEY'], @card, @amount
    rescue Paypal::UnprocessablePayment => e
    Rails.logger.error "Payment unprocessable, try again."
    return false
    end
    end
    end
    ```
  14. @venkatch789 venkatch789 created this gist Jul 17, 2015.
    50 changes: 50 additions & 0 deletions gistfile1.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,50 @@
    #### Ruy Design patterns

    * Design patterns are just tools that help us constructing a software.

    ** Template Method pattern
    In the *Template Method* pattern, we create a *skeletal class* and it is basis for various *subclasses* or *concrete classes*. Within in the skeletal class, there are abstract methods, which in turn, will be overridden by the methods of subclasses.

    Let's take an example of **simple payment system**,

    Usually, the payment process has the same flow regardless of the provider we use.

    The flow of our example payment system is,
    1. Authenticate the merchant (our application) with the provider
    2. Send the User's card data with the amount of order
    3. Receive confirmation or error from the provider

    ```
    class StripePayment
    def initialize card, amount
    @api_key = ENV['STRIPE_API_KEY']
    @card = card
    @amount = amount
    end
    def process_payment!
    authenticate_merchant && make_payment
    end
    def authenticate_merchant
    begin
    return true if Stripe::Merchant.authenticate @api_key
    rescue Stripe::MerchantError => e
    Rails.logger.error "Cannot establish connection between Merchant and Provider."
    return false
    rescue Stripe::ProviderUnreachable => e
    Rails.logger.error "Provider unreachable."
    return false
    end
    end
    def make_payment
    begin
    return true if Stripe::Payment.process! @api_key, @card, @amount
    rescue Stripe::PaymentUnprocessable => e
    Rails.logger.error "Payment unprocessable, try again."
    return false
    end
    end
    end
    ```