Pass it a block as an argument
def my_method(&block)
do_something_the_same
yield # calls whatever is inbetween "do" and "end"
end
Question
I keep writing the same pattern of code in Ruby, which seems like it would benefit from a 'do' style bit of code but I'm not sure how to write the method.
I keep doing this pattern of code, which starts and ends with the same lines of code...
x.increment!(:step_count) # same each time
# ...then some different code each
x.update_column(:step_description, "blerg message") # same each time
I feel it would benefit from a 'do' something that would look like this...
update_steps "blerg message" do
# ...then some different code each
end
And then inside the 'do' each time it does the common code.
How would I go about making a method where I can use a 'do'.
Thanks!
Edit: I think it's important to not close this because I didn't know to search for 'block' or 'yield'. People who may no know these terms may end up searching for 'do' instead.
La solution 2
Pass it a block as an argument
def my_method(&block)
do_something_the_same
yield # calls whatever is inbetween "do" and "end"
end
Autres conseils
Creating methods that accept a block is one of Ruby's most powerful features.
The common way to define such a method would be:
def foo(*args, &block)
# your code here
yield
# some more code
end
foo do
# This code runs when yield is called
end
There are a few things you should know about the above:
The &block
parameter is not required. You can just use yield
anyway. But there are a few reasons why you should add it to your method definition:
&
basically transforms the block to a proc
object. This could be handy since that way you can actually pass it around as a parameter to another method that accepts a block. You just need to re-apply the &
to make it again a block.proc
object can be more powerful since you can also set its binding.You can pass arguments to yield
. The arguments you pass are the block local variables. For example in:
[1,2,3].each {|x| puts x}
yield
is called with one of the array elements on every iteration. Calling yield
with an argument is the same as block.call(a)
where a
is an argument.
If your method encounters a yield
and there is no block given it will raise an exception. This might be correct in some cases. But if you want to have a different behavior if no block is given you can use the block_given?
method to check it.
&block
must be the last parameter in your method definition.Or you can also do this by calling block.call
def update_steps(&block)
block.call()
end