Blocks and procs

Just curious, I'm just learning about Procs, and have already looked at
using blocks.
Are they very close in the way they function. It seems that way to me.
Perhaps I'm wrong.
Is one favoured above the other ?

TIA
Stuart

Hi --

Just curious, I'm just learning about Procs, and have already looked at
using blocks.
Are they very close in the way they function. It seems that way to me.
Perhaps I'm wrong.
Is one favoured above the other ?

They're different things. A block is a syntactic construct, part of a
method call. A Proc object is an object.

They are, however, closely related. Using special argument syntax, a
method can turn the block supplied to it into a Proc:

   def meth(&block)
     # block is the Proc version of the block
     block.call # etc.
   end

   meth { # this is the block }

Also, you can use Proc objects as block substitutes:

   meth &some_proc_object

David

···

On Wed, 12 Jul 2006, Dark Ambient wrote:

--
http://www.rubypowerandlight.com => Ruby/Rails training & consultancy
Ruby for Rails => RUBY FOR RAILS, the Ruby book for
                                                     Rails developers
http://dablog.rubypal.com => D[avid ]A[. ]B[lack's][ Web]log
dblack@wobblini.net => me

I see David has already answered your question here, but just in case it helps I wrote about this on my blog a while back:

James Edward Gray II

···

On Jul 11, 2006, at 11:55 AM, Dark Ambient wrote:

Just curious, I'm just learning about Procs, and have already looked at
using blocks.
Are they very close in the way they function. It seems that way to me.
Perhaps I'm wrong.
Is one favoured above the other ?

Good example. Also because it's rails centric (something I'd eventually
like to get to)
I am running into some select errors though , via the select statement. If
your up to reading it through (I don't find any typos matched against your
code), if not that is fine as the explanation helped me.

class ClientDB
  Record = Struct.new(:client_name, :location, :projects)

  def initialize
    @records = [ Record.new("Gray Productions", "Oklahoma",
                      ["Ruby Quiz", "Rails Extensions"] ),
                      Record.new( "Serenity Crew", "Deep Space",
                      ["Ship Enhancements"] ),
                      Record.new( "Neo", "Hollywood",
                      ["Rails interface for the Matrix"] ) ]
                    end # end of method

    def select( query )
      # parse query String
      rules = Hash[*query.split(/\s*AND\s*/).map do |rule|
        rule.split(/\s*=\s*/).map { |value| value.sub(/^['"](.+)['"]$/,
'\1') }
        end.flatten ]

      #match records
      @records.select { |record| block_given? and yield record }
        rules.all? { |field, value| record.send(field) == value }

    end # end of method

end # end of class

  require "pp"
  db = ClientDB.new
  pp db.select { |record| record.client_name != "Gray Productions" }
  pp db.select { |record| record.client_name +~ /crew/i }
  pp db.select { |record| record.projects.size == 1 }
  pp db.select { |record| record.projects.include? "Ruby Quiz" }

···

--------

On 7/11/06, James Edward Gray II <james@grayproductions.net> wrote:

On Jul 11, 2006, at 11:55 AM, Dark Ambient wrote:

> Just curious, I'm just learning about Procs, and have already
> looked at
> using blocks.
> Are they very close in the way they function. It seems that way to
> me.
> Perhaps I'm wrong.
> Is one favoured above the other ?

I see David has already answered your question here, but just in case
it helps I wrote about this on my blog a while back:

Gray Soft / Not Found

James Edward Gray II

oops...this is the error:

rb:32:in `select': wrong number of arguments (0 for 1) (ArgumentError)

···

On 7/11/06, Dark Ambient <sambient@gmail.com> wrote:

Good example. Also because it's rails centric (something I'd eventually
like to get to)
I am running into some select errors though , via the select statement.
If your up to reading it through (I don't find any typos matched against
your code), if not that is fine as the explanation helped me.

class ClientDB
  Record = Struct.new(:client_name, :location, :projects)

  def initialize
    @records = [ Record.new("Gray Productions", "Oklahoma",
                      ["Ruby Quiz", "Rails Extensions"] ),
                      Record.new( "Serenity Crew", "Deep Space",
                      ["Ship Enhancements"] ),
                      Record.new( "Neo", "Hollywood",
                      ["Rails interface for the Matrix"] ) ]
                    end # end of method

    def select( query )
      # parse query String
      rules = Hash[*query.split(/\s*AND\s*/).map do |rule|
        rule.split(/\s*=\s*/).map { |value| value.sub(/^['"](.+)['"]$/,
'\1') }
        end.flatten ]

      #match records
      @records.select { |record| block_given? and yield record }
        rules.all? { |field, value| record.send(field) == value }

    end # end of method

end # end of class

  require "pp"
  db = ClientDB.new
  pp db.select { |record| record.client_name != "Gray Productions" }
  pp db.select { |record| record.client_name +~ /crew/i }
  pp db.select { |record| record.projects.size == 1 }
  pp db.select { |record| record.projects.include? "Ruby Quiz" }

--------

On 7/11/06, James Edward Gray II < james@grayproductions.net> wrote:
>
> On Jul 11, 2006, at 11:55 AM, Dark Ambient wrote:
>
> > Just curious, I'm just learning about Procs, and have already
> > looked at
> > using blocks.
> > Are they very close in the way they function. It seems that way to
> > me.
> > Perhaps I'm wrong.
> > Is one favoured above the other ?
>
> I see David has already answered your question here, but just in case
> it helps I wrote about this on my blog a while back:
>
> Gray Soft / Not Found
>
> James Edward Gray II
>

I am running into some select errors though , via the select statement.

Sure I see the trouble...

require "pp"
db = ClientDB.new
pp db.select { |record| record.client_name != "Gray Productions" }
pp db.select { |record| record.client_name +~ /crew/i }
pp db.select { |record| record.projects.size == 1 }
pp db.select { |record| record.projects.include? "Ruby Quiz" }

In order to run this example, you need to use the select() code in the article, just a paragraph above it. I'm slowly making changes and refining a solution as I go.

Hope that helps.

James Edward Gray II

···

On Jul 11, 2006, at 1:18 PM, Dark Ambient wrote:

hmmmm....i have that code in there:

···

   def select( query )
     # parse query String
        rules = Hash[*query.split(/\s*AND\s*/).map do |rule|
        rule.split(/\s*=\s*/).map { |value| value.sub(/^['"](.+)['"]$/,
'\1') } end.flatten ]

        #match records
         @records.select { |record| block_given? and yield record }
          rules.all? { |field, value| record.send(field) == value }

    end # end of method

end # end of class

On 7/11/06, James Edward Gray II <james@grayproductions.net> wrote:

On Jul 11, 2006, at 1:18 PM, Dark Ambient wrote:

> I am running into some select errors though , via the select
> statement.

Sure I see the trouble...

> require "pp"
> db = ClientDB.new
> pp db.select { |record| record.client_name != "Gray Productions" }
> pp db.select { |record| record.client_name +~ /crew/i }
> pp db.select { |record| record.projects.size == 1 }
> pp db.select { |record| record.projects.include? "Ruby Quiz" }

In order to run this example, you need to use the select() code in
the article, just a paragraph above it. I'm slowly making changes
and refining a solution as I go.

Hope that helps.

James Edward Gray II

That's from higher up in the article. Here's the one just before the example you showed:

   class ClientDB
     def select
       @records.select { |record| block_given? and yield record }
     end
   end

Try that.

James Edward Gray II

···

On Jul 11, 2006, at 2:31 PM, Dark Ambient wrote:

hmmmm....i have that code in there:

   def select( query )
     # parse query String
        rules = Hash[*query.split(/\s*AND\s*/).map do |rule|
        rule.split(/\s*=\s*/).map { |value| value.sub(/^['"](.+)['"]$/,
'\1') } end.flatten ]

        #match records
         @records.select { |record| block_given? and yield record }
          rules.all? { |field, value| record.send(field) == value }

    end # end of method

end # end of class

Got it, had to remove the former query.
Working now, on to lamda.

Stuart

···

On 7/11/06, James Edward Gray II <james@grayproductions.net> wrote:

On Jul 11, 2006, at 2:31 PM, Dark Ambient wrote:

> hmmmm....i have that code in there:
>
>> def select( query )
>> # parse query String
>> rules = Hash[*query.split(/\s*AND\s*/).map do |rule|
>> rule.split(/\s*=\s*/).map { |value| value.sub(/^['"](.+)
>> ['"]$/,
>> '\1') } end.flatten ]
>>
>> #match records
>> @records.select { |record| block_given? and yield record }
>> rules.all? { |field, value| record.send(field) == value }
>>
>> end # end of method
>>
>> end # end of class

That's from higher up in the article. Here's the one just before the
example you showed:

   class ClientDB
     def select
       @records.select { |record| block_given? and yield record }
     end
   end

Try that.

James Edward Gray II