Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to refer to a parameter passed to a method within the passed block in ruby?

Tags:

ruby

block

I hope I am not repeating anyone here, but I have been searching google and here and not coming up with anything. This question is really more a matter of "sexifying" my code.

What I am specifically trying to do is this:

Dir.new('some_directory').each do |file|
  # is there a way to refer to the string 'some_directory' via a method or variable?
end

Thanks!

like image 645
Andrew Haust Avatar asked May 16 '12 22:05

Andrew Haust


People also ask

How do you pass a method as a parameter in Ruby?

The symbol terminology is Ruby's built-in way to allow you to reference a function without calling it. By placing the symbol in the argument for receives_function, we are able to pass all the info along and actually get into the receives_function code block before executing anything.

Is Ruby pass by value or pass by reference?

Ruby is pass-by-value, but the values it passes are references. A function receives a reference to (and will access) the same object in memory as used by the caller.

How would you define a method accepting a block with parameters?

We can explicitly accept a block in a method by adding it as an argument using an ampersand parameter (usually called &block ). Since the block is now explicit, we can use the #call method directly on the resulting object instead of relying on yield .

What is &Block in Ruby?

A block is the same thing as a method, but it does not belong to an object. Blocks are called closures in other programming languages. There are some important points about Blocks in Ruby: Block can accept arguments and returns a value. Block does not have their own name.


2 Answers

Not in general; it's totally up to the method itself what arguments the block gets called with, and by the time each has been called (which calls your block), the fact that the string 'some_directory' was passed to Dir.new has been long forgotten, i.e. they're quite separate things.

You can do something like this, though:

Dir.new(my_dir = 'some_directory').each do |file|
    puts "#{my_dir} contains #{file}"
end
like image 192
Asherah Avatar answered Nov 28 '22 22:11

Asherah


The reason it won't work is that new and each are two different methods so they don't have access to each others' parameters. To 'sexify' your code, you could consider creating a new method to contain the two method calls and pass the repeated parameter to that:

def do_something(dir)
  Dir.new(dir).each do |file|
    # use dir in some way
  end
end

The fact that creating a new method has such a low overhead means it's entirely reasonable to create one for as small a chunk of code as this - and is one of the many reasons that make Ruby such a pleasure of a language to work with.

like image 24
Russell Avatar answered Nov 28 '22 20:11

Russell