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.

Was it helpful?

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

OTHER TIPS

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:

  1. 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:

    • It makes it clear that your method accepts a block
    • The & 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.
    • Handling a proc object can be more powerful since you can also set its binding.
  2. 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.

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

  4. &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
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top