Stupid question about blocks in before_validation for eg

Hi,

I'm hitting a wall in my ruby knowledge. When I have:

before_validation { |object| object.permalink =
object.title.parameterize }

What's that { |object| ...} thing? It's a block, ok, but when does it
get executed? When and where does object come from?

I tried digging in the Rails source code, but there is a lot going on so
I'm getting confused.

I'm asking this question because my real problem is the following:

I'm using the paperclip plugin for one of my rails app, and here is the
code I am trying to make work:

class Asset < ActiveRecord::Base

  has_attached_file :data, :styles => {
    :theora => [:format => :ogv, :processors => lambda {|a| a.video? ?
[:video_converter] : []}}]
}

end

What fails is the lambda, because in Paperclip behind the scenes this is
what happens (edited for brevity):

@some_var = style.processors.inject(something) do |file, processor|
...
end

style.processors has received the lambda defined earlier. But doesn't it
get the asset object and get executed when the interpreter hits the line
like the before_validation does?

So I get the following error message:

NoMethodError (undefined method `inject' for #<Proc:0x455d864>)

How can I fix this problem?

Surprisingly if I define the following, the lambda does not cause to
crash:

has_attached_file :data, :styles => {
  :theora => [:format => :ogv],
  :processors => lambda {|a| a.video? ? [:video_converter] : []}
}

Can someone shed some light on this lambda thing? And after that which
book or resources can I read to get proficient in such dynamic coding
practice? Currently in use blocks all the time ([array].each { ...})
without really mastering them.

Thanks for your support

Hi,

I'm hitting a wall in my ruby knowledge. When I have:

before_validation { |object| object.permalink =
object.title.parameterize }

What's that { |object| ...} thing? It's a block, ok, but when does it
get executed? When and where does object come from?

That depends entirely on what the before_validation does. In general
such a method could call it straight away or it could stash away the
block for use at some later point. According to the active record docs
that block will be called before an object is validated and the
parameter passed to the block is the object in question.

I'm asking this question because my real problem is the following:

I'm using the paperclip plugin for one of my rails app, and here is the
code I am trying to make work:

class Asset < ActiveRecord::Base

has_attached_file :data, :styles => {
:theora => [:format => :ogv, :processors => lambda {|a| a.video? ?
[:video_converter] : []}}]

}

end

What fails is the lambda, because in Paperclip behind the scenes this is
what happens (edited for brevity):

@some_var = style.processors.inject(something) do |file, processor|
...
end

style.processors has received the lambda defined earlier. But doesn't it
get the asset object and get executed when the interpreter hits the line
like the before_validation does?

So I get the following error message:

NoMethodError (undefined method `inject' for #<Proc:0x455d864>)

How can I fix this problem?

That's just saying that it was expect an array of lambdas, rather than
a single one - i suppose the clue there (other than the paperclip
source code & docs) is that the option is called processors (ie a
plural)

Surprisingly if I define the following, the lambda does not cause to
crash:

has_attached_file :data, :styles => {
:theora => [:format => :ogv],
:processors => lambda {|a| a.video? ? [:video_converter] : []}

}

paperclip probably isn't expecting the :processors option there and is
just ignoring it.

Can someone shed some light on this lambda thing? And after that which
book or resources can I read to get proficient in such dynamic coding
practice? Currently in use blocks all the time ([array].each { ...})
without really mastering them.

In a nutshell lambda turns a bloc into a Proc object that you can pass
around and manipulate like any other object.
Have you read the pickaxe?

Fred

paperclip probably isn't expecting the :processors option there and is
just ignoring it.

No it is a valid option here and gets executed correctly.

Have you read the pickaxe?

I'll read it again, I probably went too quickly over a few chapters the
first times :slight_smile: