#### 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* #### Design patterns in Ruby? 1. TEMPLATE METHOD 2. OBSERVER 3. DECORATOR 4. SINGLETON 5. FACTORY #### 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`