[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Using a block to surround a string?

m.ann robertson

7/3/2007 11:35:00 PM

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).

So I wanted to know what's the best way to accomplish what I'm trying to
do...

Thanks for your patience :)

- Ivan V.

--
Posted via http://www.ruby-....

7 Answers

SonOfLilit

7/3/2007 11:47:00 PM

0

Read in the pickaxe about passing a hash of parameters to a method
(like Rails does a lot)


Aur

On 7/4/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).
>
> So I wanted to know what's the best way to accomplish what I'm trying to
> do...
>
> Thanks for your patience :)
>
> - Ivan V.
>
> --
> Posted via http://www.ruby-....
>
>

Gregory Brown

7/3/2007 11:58:00 PM

0

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

dblack

7/4/2007 12:08:00 AM

0

Pete Yandell

7/4/2007 12:11:00 AM

0

Ivan Vega wrote:

> around_string('mystring') {|b, a| b = 'before'; a = 'after';}

You want:

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

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

And you wnat:

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

For a quick intro to blocks, see the five minute talk I gave on them
last week:

http://www.cogentconsulting.com.au/screencasts/...

A block, however, seems like a terrible way of doing this. Have you
considered using an options hash?

around_string('mystring', :before => 'before', :after => 'after')

def around_string(string, *options)
"#{options[:before]}#{string}#{options[:after]}"
end


Pete Yandell
http://no...

dblack

7/4/2007 12:16:00 AM

0

Gregory Brown

7/4/2007 12:19:00 AM

0

On 7/3/07, Matt Greer <matt.e.greer@gmail.com> wrote:

> Is the &block parameter necessary? When is it necessary?

You should not use &block and yield together. Use one or the other.

&block is necessary when you are passing a block to another method.

e.g.

def foo(&a)
puts "In foo"
bar(&a)
end

def bar
puts "In bar"
yield
end

foo { puts "in block" }

OUTPUT:

In foo
In bar
in block

> And so I take it with blocks, they are given a new reference to the objects
> in question and therefore assigning to the variables in the block has no
> effect on the method. ie

> def around_string(string, &block)
> b = nil
> a = nil
> yield(b,a)
> "#{b}#{string}#{a}"
> end
>
> around_string('center') { |b, a| b = 'left'; a = 'right' }

> is worthless because in the block I'm merely assigning objects to local
> references that go out of scope once the block exits?

Right, block local variables that are defined within the block
disappear when the block exits. Blocks can access and modify local
variables in the scope the *block* is defined, but not within the
method.

Here's a set of examples all rolled together for that:

def foo
a = 1
yield(a)
puts "a in method #{a}"
end

b = 3

puts "b before block: #{b}"

foo { |a| b += 2; a += 1; puts "a in block: #{a}" }

OUTPUTS:

b before block: 3
a in block: 2
a in method 1
b after block: 5
puts "b after block: #{b}"

Gregory Brown

7/4/2007 12:20:00 AM

0

small correction...

On 7/3/07, Gregory Brown <gregory.t.brown@gmail.com> wrote:
> On 7/3/07, Matt Greer <matt.e.greer@gmail.com> wrote:

> Here's a set of examples all rolled together for that:
>
> def foo
> a = 1
> yield(a)
> puts "a in method #{a}"
> end
>
> b = 3
>
> puts "b before block: #{b}"
>
> foo { |a| b += 2; a += 1; puts "a in block: #{a}" }

> puts "b after block: #{b}"

> OUTPUTS:
>
> b before block: 3
> a in block: 2
> a in method 1
> b after block: 5