On 7/3/07, Ivan Vega <afraid / spam.com> wrote:
> Hi,
>
> I'm trying something very simple, like passing a method a string, and
> two more strings to surround that with... i.e.:
>
> around_string('mystring') {|b, a| b = 'before'; a = 'after';}
>
> The method:
>
> def around_string(string, &block)
>     b, a = yield
>     "#{b}#{string}#{a}"
> end
>
> That of course doesn't work because I still don't get how blocks and
> procs work and what they are. The reason I don't just pass 'a' and 'b'
> as parameters to the method is because the method has other parameters I
> don't want to touch, and it seemed like a block as the last parameter
> would be a good choice (I simplified my example so it's clearer).

SonOfLilit makes the best suggestion, you can just use a hash as your
last parameter

def around_string(string,other,args,options={})
  # whatever
  "#{options[:left]}#{string}#{options[:right]}"
end

around_string "foo", ..., :left => "$", :right => "!"

But here's some background on blocks.

def foo
  a = yield # a gets the return value of the block
  a + 1
end

foo { 4 } #=> 5

def foo
  a = yield(3,5) # a passes 3 and 5 to the block
  a + 1
end

foo { |b,c| b * c } #=> 16

So you see, you need to pass values to yield for them to be passed
into the block, and the result of the yield is just whatever the block
evaluates to.

Because it's a closure you can also use things in the local scope.

d = 5
foo { |b,c| b * c + d } #=> 21

So if you *really* wanted to use blocks in your original example, you could do:

def around_string(string, &block)
     b, a = yield
     "#{b}#{string}#{a}"
end

around_string('mystring') { ['before','after'] }

But that is ugly and unidiomatic. :)

Hope this helps,
-greg