views:

158

answers:

2

Hi, hereafter is my piece of code that I want to simplify in order to avoid passing an extra argument on each call. In fact, my usecase is that M is a user library without the definition of context argument on each method. check is a method that is not defined by the user.

# User code
module M
  def do_something(context)
    puts "Called from #{context}"
    context.check
  end
  module_function :do_something
end

# Application code
class Bar
  def check
    puts "Checking from #{self}..."
  end
end

class Foo < Bar
  def do_stuff(scope, method)
    scope.send method, self
  end
end

# Executed by user
Foo.new.do_stuff M, :do_something

Is there a way to do the same think without passing self as an input argument to do_something method in order to retrieve check method ?

# User code
module M
  def do_something
    called_from_object = ???
    puts "Called from #{called_from_object}"
    called_from_object.check
  end
  module_function :do_something
end

# Application code
class Bar
  def check
    puts "Checking from #{self}..."
  end
end

class Foo < Bar
  def do_stuff(scope, method)
    scope.send methood
  end
end

# Executed by user
Foo.new.do_stuff M, :do_something

Thanks for your support!

A: 

Not what you're asking for, but if Foo were to include M would that allow you do achieve what you're after? e.g.

module M
  def do_something
    puts "I am going to use the test method from the including class"
    test
  end
end

class Foo
  include M
  def test
    puts "In Foo's test method"
  end

  def do_stuff
    do_something
  end
end

and then you can do:

irb(main):019:0> Foo.new.do_stuff
I am going to use the test method from the including class
In Foo's test method

If the idea is to have a module provide some general functionality and have the specifics in a class then this is a fairly common pattern in ruby, e.g. the Comparable module requiring the including class to implement <=>.

mikej
I had a look on Comparable module but I don't see the link between my issue and that module... Can you go more into details?
David
When the module was fixed as a specific module (e.g. `M` in your original version of the question) then the class `Foo` could just include `M` and then when `do_stuff` called the included `do_something` self would be the instance of Foo. However if the module is being passed as a parameter do do_stuff (as in the updated example) then I think you will need a different approach.
mikej
Thanks for this feedback, I agree in case of a particular module `M`. My initial post was a specific case that did no reflect what I really want to do.
David
Cool. Thanks for the feedback from your side too. Hopefully someone else will be along with an alternative suggestion.
mikej
A: 

Came across this post while looking for an answer for my own purposes.

Didn't find one that was appropriate, so I dug through the Ruby source and put together an extension. I've bundled it as a gem- should install without any problem so long as you are using Ruby 1.9.1:

sudo gem install sender

This will not work with Ruby 1.8, as 1.8 has a different model for tracking frames.

http://rubygems.org/gems/sender

Asher