when should I used Lambda or Anonymous method? - ruby-on-rails

I understand the working of block , proc and lambda experession but what i dont understand that when to use anonymous method in code.
What is the problem which Anonymous solves ?

One very common usage of lambdas is for lazy-loading of (and passing parameters to) ActiveRecord relations in scopes:
class Post < ActiveRecord::Base
scope :recent, lambda { |today| where('published_at >= ?', today) }
end
(from here)
In general though, these closure methods are a concise way of operating on (e.g.) a collection of data all at once, or storing code as data to be passed around to other functions.

One of the reasons I use lambdas in this way in Ruby is when I need a closure to capture stuff from the surrounding scope, which for example in smaller scripts I sometimes find more convenient than passing things around as arguments. Other people (ab)use top-level instance variables for that, but I don't like that much.
Update as requested: Here's a little example:
shift_timestamp = -> ts do
t = Time.parse(ts.gsub(',','.')) + options[:time]
"#{t.strftime("%H:%M:%S")},#{t.usec.to_s[0..2]}"
end
This is for a little tool I wrote for shifting subtitles. It's a short script and writing it this way allowed me to close over options and access it inside the lambda without having to pass it in. As I said, nothing funky, but for small scripts I sometimes like to do this (where "this" is parsing options, writing 1 or 2 lambdas that use those options, use the lambdas instead of methods later on).

Related

Why isn't the args parameter used in ActionController::Instrumentation::render?

I am new to Ruby and to Rails, and am trying to understand fully what I'm reading.
I am looking at some of the Rails source code, in this case action_controller/metal/instrumentation.rb.
def render(*args)
render_output = nil
self.view_runtime = cleanup_view_runtime do
Benchmark.ms { render_output = super }
end
render_output
end
I understand that *args is using the splat operator to collect the arguments together into an array. But after that, it stops making much sense to me.
I can't fathom why render_output is set to nil before being reassigned to equal super and then called with no arguments. I gather that some speedtest is being done, but coming from other languages I'd expect this to just be something more like Benchmark.ms(render_output) or perhaps Benchmark.start followed by render_output followed by Benchmark.end. I'm having a hard time following the way it works here.
But more importantly, I don't really follow why args isn't used again. Why bother defining a param that isn't used? And I mean, clearly it is getting used-- I just don't see how. There's some hidden mechanism here that I haven't learned about yet.
In this context, it is important to note how super works, because in some cases it passes implicitly arguments and you might not expect that.
When you have method like
def method(argument)
super
end
then super is calling the overridden implementation of method implicitly with the exact same arguments as the current method was called. That means in this example super will actually call super(argument).
Of course, you can still define a method call that explicitly sends other arguments to the original implementation, like in this example:
def method(argument)
super(argument + 1)
end
Another important edge-case is when you want to explicitly call super without any arguments although the current method was called with arguments then you need to be very explicit like this
def method(argument)
super() # note the empty parentheses
end
Let me try to describe you what I think this code does.
*args*
is using the splat operator to collect the arguments together into an array
that is totally correct, however they don't use it, and if you will go to master branch, they just changed it to *. Asking why it is defined and not used, I think that's question about bad design. They should have called it _args or at least like it is now just single splat *.
render_output is set to nil because of scopes, it has to be explicitly defined out block, lambda, proc in order to store value in it, otherwise its visibility will be locked only to those lambda, proc, block execution. Refer to this article
Benchmark.start. Blocks are great ruby construction. You are totally correct that speedtest is done, we can see it is just decorator for benchmark library.
source.
You are wondering why we cannot just pass it as Benchmark.ms(render_output), that's because what will be given to benchmark ms function? It will be given result, like <div> my html </div. And how we can measure this string result - no how. That's why we calling super right in this block, we want to access parent class function and wrap it inside block, so we are not calling it, we just construct it, and it will be called inside benchmark lib, and measured execution like
class Benchmark
...
def realtime # :yield:
r0 = Process.clock_gettime(Process::CLOCK_MONOTONIC)
yield
Process.clock_gettime(Process::CLOCK_MONOTONIC) - r0
end
...
end
So here we can count realtime of function execution, this is the code from original library

ActiveJob: how to do simple operations without a full blown job class?

With delayed_job, I was able to do simple operations like this:
#foo.delay.increment!(:myfield)
Is it possible to do the same with Rails' new ActiveJob? (without creating a whole bunch of job classes that do these small operations)
ActiveJob is merely an abstraction on top of various background job processors, so many capabilities depend on which provider you're actually using. But I'll try to not depend on any backend.
Typically, a job provider consists of persistence mechanism and runners. When offloading a job, you write it into persistence mechanism in some way, then later one of the runners retrieves it and runs it. So the question is: can you express your job data in a format, compatible with any action you need?
That will be tricky.
Let's define what is a job definition then. For instance, it could be a single method call. Assuming this syntax:
Model.find(42).delay.foo(1, 2)
We can use the following format:
{
class: 'Model',
id: '42', # whatever
method: 'foo',
args: [
1, 2
]
}
Now how do we build such a hash from a given call and enqueue it to a job queue?
First of all, as it appears, we'll need to define a class that has a method_missing to catch the called method name:
class JobMacro
attr_accessor :data
def initialize(record = nil)
self.data = {}
if record.present?
self.data[:class] = record.class.to_s
self.data[:id] = record.id
end
end
def method_missing(action, *args)
self.data[:method] = action.to_s
self.data[:args] = args
GenericJob.perform_later(data)
end
end
The job itself will have to reconstruct that expression like so:
data[:class].constantize.find(data[:id]).public_send(data[:method], *data[:args])
Of course, you'll have to define the delay macro on your model. It may be best to factor it out into a module, since the definition is quite generic:
def delay
JobMacro.new(self)
end
It does have some limitations:
Only supports running jobs on persisted ActiveRecord models. A job needs a way to reconstruct the callee to call the method, I've picked the most probable one. You can also use marshalling, if you want, but I consider that unreliable: the unmarshalled object may be invalid by the time the job gets to execute. Same about "GlobalID".
It uses Ruby's reflection. It's a tempting solution to many problems, but it isn't fast and is a bit risky in terms of security. So use this approach cautiously.
Only one method call. No procs (you could probably do that with ruby2ruby gem). Relies on job provider to serialize arguments properly, if it fails to, help it with your own code. For instance, que uses JSON internally, so whatever works in JSON, works in que. Symbols don't, for instance.
Things will break in spectacular ways at first.
So make sure to set up your debugging tools before starting off.
An example of this is Sidekiq's backward (Delayed::Job) compatibility extension for ActiveRecord.
As far as I know, this is currently not supported. You can easily simulate this feature using a custom-defined proxy-job that accepts a model or instance, a method to be performed and a list of arguments.
However, for the sake of code testing and maintainability, this shortcut is not a good approach. It's more effective (even if you need to write a little bit more of code) to have a specific job for everything you want to enqueue. It forces you to think more about the design of your app.
I wrote a gem that can help you with that https://github.com/cristianbica/activejob-perform_later. But be aware that I believe that having methods all around your code that might be executed in workers is the perfect recipe for disaster is not handled carefully :)

Rails: What's the difference between lambda, scope and class method? What's best practice?

The code snippet has three methods: lambda, scope and class method.
All of them returns the same results.
Questions:
Is there any best practice in Ruby/Rails when it is preferred to use one over the other ?
In what cases would you use lambda, scope or class method ( best practices ).
class Cars < ActiveRecord::Base
attr_accessible :manufacturer, :price, :used
#one
scope :used_and_cheap_lambda, lambda { where('used = ?', true ).where('price >= ?',30000) }
#two
scope :used_and_cheap_scope, where('used = ?', true ).where('price >= ?',30000)
#three
def self.used_and_cheap_class
where('used = ?', true ).where('price >= ?',30000)
end
end
Cars.used_and_cheap_lambda.count
=> #24
Cars.used_and_cheap_class.count
=> #24
Cars.used_and_cheap_scope.count
=> #24
It's best to avoid using option 2. That code gets run immediately when your Rails app loads which is bad since it will always return the same value for any Time argument you use in it. That's because it isn't reevaluated every time it's called.
Option 1, as pointed out by musicnerd47, are lazy loaded and it is advisable that you pass lambdas to scopes in Rails 4 rather than doing option 2 since they are reevaluated every time called so they will return updated values.
So the only options would be 1 and 3. This is usually a matter of style that your team adheres to. In our company, we use option 1 when the code we pass to it is going to be an ActiveRecord query and we want it to output a query that can be chained. This is to ensure that an ActiveRecord::Relation object is returned every time we do our queries for multiple records. That would mean that they are always going to be chainable with other ActiveRecord::Relation methods and our other defined scopes.
We use option 3 if it's for behavior that doesn't need to be chained with other scopes.
Here's a good read on the matter of scopes and class_methods where he goes into detail and provides examples on the difference between scopes and class methods.
http://blog.plataformatec.com.br/2013/02/active-record-scopes-vs-class-methods/
Starting in Rails 4 you have to use a lambda - in general it is a better practice because it is lazily loaded and prevents a lot of traps, especially when dealing with dates and times.
I think for simple scopes that deal with a single where call or something, using scope is okay. When it is more complex, then moving to a class method is better (for example, when you need to be calling other methods or setting local variables before you return the scope).
I would use the lambda. The function you're describing is sufficiently simple. Using the lambda initializes lazily as well. I direct you here to the rails style guide.
Unfortunately there is no golden rule. Scopes are designed for this exact application. When the application of logic comfortably fits into a scope, I think that's the best bet. When things start to get too complex, it's usually best to move the logic into a class method.

How would I use Procs in Ruby on Rails?

There are a few helpers I am using in my project, which I just thought that I could maybe treat as Procs, as they do very specific tasks and can be used by very different components.
I've used Procs in small Ruby projects, mainly when learning the language, and I thought that this would be a good occasion to put them to use.
My question is, where would I put the Procs in the Rails folder structure? Are there any guidelines or reccomdendations for this? Is it considered good practice?
I am a bit puzzled what the advantage would be of using Procs over using simple methods? So if you could give some examples, that would be nice.
Anyways: since Procs can be stored in a variable, I would declare a module inside the lib folder, and define the procs as variables, constants, or methods returning the proc. Something like this
module ProcContainer
def proc_1(factor)
Proc.new { |n| n*factor }
end
PROC_2 = Proc.new { |n| 2 * n }
end
which would be used as
gen_proc = ProcContainer.proc_1(6)
result = gen_proc(3)
other_proc = ProcContainer.PROC_2(4)
The advantage of the method is obvious i guess, since it will return a new Proc object every time it is called, while the constant is only evaluated once.
(of course you should change the naming to something more appropriate)
Ruby has amazing syntax for blocks, so we tend to favor them over explicitly making procs. The downside of blocks is that they need to be executed immediately when the called method yields to them (procs don't have that limitation). That is in place for performance reasons, but you can easily package up a block as a proc, and store it somewhere else for later, or pass it down to another method. So even though you are probably using procs every day, you don't really realize it, because your interface to them is through the block syntax.

Allow the user to pick a named scope via GET params

In my posts model, I have a named scope:
named_scope :random, :order => "Random()"
I'd like to give users the ability to get posts in a random order by sending a GET request with params[:scope] = 'random'.
Short of eval("Post.#{params[:scope]}"), how can I do this?
I would suggest my very awesome acts_as_filter plugin designed for user-driven filtering of results via named_scopes.
http://github.com/tobyhede/acts_as_filter/tree/master
Eval is fine to use - but make sure you validate against accepted/expected values (I often just plug some values into an array and test accepted_values.include?(parameter))
eval is a pretty bad idea. However, #send is perfect for this - it's inherently safer, and faster than eval (as I understand it).
Product.send(params[:scope])
That should do it :)
I came across it in a search. searchlogic is perfect for this.
I would stay away from eval since you're dealing with data that comes from the user. Maybe just use a simple case statement? This way you'll be able to validate what the data they're giving you.
For the example you give, I'd be explicit, and chain scopes together to build the query you want:
scope = Post
scope = scope.random if params[:scope] == 'random'
#posts = scope.find(:all, ...) # or paginate or whatever you need to do
If params[:scope] isn't 'random', this is the same as calling Post.find(), otherwise it's doing Post.random.find()
From one of the other answers, it looks like find_by_filter would do pretty much the same thing for you.
Using this pattern, you can also combine multiple scopes into the query if you needed to support things that weren't mutually exclusive
e.g.
scope = scope.only_monsters if params[:just_monsters] == 1
scope = scope.limit(params[:limit].to_i) unless params[:limit].to_i.zero?
So GETting /posts?scope=random&just_monsters=1&limit=5 will give you:
Post.random.just_monsters.limit(5).find(:all, ...)

Resources