Before getting into the differences, they are very similar and both are Proc objects.
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.
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)
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.
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)
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
- TEMPLATE METHOD
- OBSERVER
- DECORATOR
- SINGLETON
- FACTORY
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.
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.
Dog.class_eval do
def bark
puts "huf huf..."
end
end
..is same as,
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.
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,
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,
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
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
There are several ways to create a rake task.
- Create it from scratch
- Copy-paste code from another ready rake task and change code to required.
- 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
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