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: