Private method in custom module

I have a module of custom examples, such as

module ControllerHelperMethods
module MyExampleGroupMethods
def should_set_the_body_id(body_id)
it “should set the body id to ‘#{body_id}’” do
assigns[:body_id].should == body_id
end
end
end

def self.included(receiver)
receiver.extend MyExampleGroupMethods
end
end

and in spec_helper:

Spec::Runner.configure do |config|
config.include(ControllerHelperMethods, :type => :controllers)
end

I have duplicate code in two of my custom examples, so I want to
refactor it to a private method, but I can’t seem to get the private
method to work. I have tried the most obvious way (private keyword
followed by the method), and also a couple of more clever approaches
that involved doing an instance_eval in self.included.

First, should I be able to call private methods in my custom examples?
If so, how.

Peace.
Phillip

On Thu, Dec 31, 2009 at 12:54 PM, Phillip K.
[email protected]wrote:

First of all, you can simplify this by using extend() instead of
include()
on the config object:

module ControllerMacros
def should_set_the_body_id(body_id)
it “should set the body id to ‘#{body_id}’” do
assigns[:body_id].should == body_id
end
end
end

Spec::Runner.configure do |config|
config.extend(ControllerMacros, :type => :controllers)
end

Note that we generally referred to as “macros,” so I recommend using
that
name for consistency.

I have duplicate code in two of my custom examples, so I want to
refactor it to a private method, but I can’t seem to get the private
method to work. I have tried the most obvious way (private keyword
followed by the method), and also a couple of more clever approaches
that involved doing an instance_eval in self.included.

I think that if you use extend instead of include + included hook, you
can
just use the private keyword and all will be well.

HTH,
David

Hi David,

First, thanks for the suggestion. I like that better.

Second, my motivation for doing this was born out of not being able to
do something I wanted to do in Remarkable. However, as I was trying to
explain what it was I wanted to do, I just discovered how to do it in
Remarkable. So, the immediate need for knowing how to call a private
method is no longer valid, but I would like to go ahead and explain
what I was trying to do to see if it is actually possible. I still
have custom macros that I might need to refactor at some point.

Here is the relevant code example:

[By the way, I didn’t intend for the gist to be formatted quite like
that. I am fond of 4 character tabs, but I realize that most people in
the ruby community use 2 spaces, so I copied the code to a new
textmate window, reformatted it, then copied and pasted into the gist.
But it still come out like that, so I don’t know what I’m supposed to
do.]

I was attempting to create my own should_set_session so I could use
values from instance variables. I didn’t see how to do that in
Remarkable until just a few minutes ago. It can be accomplished by
using :to => proc { @user.id }.

I was experimenting with where to call get_value_from_options from.
When I try inside the “it”, I get the NoMethodError. When I call it
from outside of the it, get_value_from_options gets called, but then I
don’t get the instance variable like I expect. I believe I understand
why that is, though. The instance var is created in the before, which
is more or less an it, so it has the same scope. So when called from
outside of the it, there is no instance var @user.

So my question now is simply: Can I even do what I want to do?

Thanks,
Phillip

David,

On Dec 31, 2:21 pm, David C. [email protected] wrote:

Make sense?

Yes. Thanks for taking the time to explain!

Peace,
Phillip

On Thu, Dec 31, 2009 at 2:05 PM, Phillip K.
[email protected]wrote:

have custom macros that I might need to refactor at some point.

Here is the relevant code example:

controller_macros.rb · GitHub

Ok - now I understand the problem :slight_smile:

You’ll see that even if you make the method public, it still won’t work.
Here’s why:

By default, the describe() method returns a class which is a subclass of
ExampleGroup. Any methods defined in the describe() block become class
methods on that subclass of ExampleGroup. The module is extending the
ExampleGroup class, so should_set_session and get_value_from_options are
both class methods.

The it() method (sort of) returns an instance of the same class. It
can
only access instance methods directly, but because it is an instance
of
the class that was extended with the module, you can
access get_value_from_options like this:


it “should set session[:#{key}]” do
value = self.class. get_value_from_options(options)

Make sense?

Cheers,
David

[By the way, I didn’t intend for the gist to be formatted quite like