1

I'm writing an acts_as_thingy module, intended to be used as per

class TestThingy
  include ActsAsThingy

  acts_as_thingy :name
end

ActsAsThingy is defined as

module ActsAsThingy

  def self.included(base)
    base.extend(ClassMethods)
  end

  module ClassMethods
    def acts_as_thingy *attributes
      attributes.each do |attribute|
        define_method attribute do
          "thingy - #{attribute.to_s}"
        end
      end
    end
  end
end

And tested as

describe ActsAsReadOnlyI18nLocalised do
  let(:thingy) { TestThingy.new }

  it 'has a name method' do
    expect(thingy.name).to eq "thingy - name"
  end
end

What happens however is that, when I run the rspec, ActsAsThingy's self.included method is never invoked, and rspec complains that there is no such method as acts_as_thingy.

I seem to be missing something entirely obvious, but just can't see it.

Why isn't the self.included method being called when I include ActsAsThingy in the class?

update

Stepping through with pry I can see that after the include ActsAsThingy, if I then look at self.included_modules it shows up as [ActsAsThingy, PP::ObjectMixin, Kernel] So the include is working, it's not a paths issue or anything like that. The core question remains; why isn't self.included being invoked?

Dave Sag
  • 13,266
  • 14
  • 86
  • 134

2 Answers2

2

So after all that it turned out that I simply needed to add

require 'acts_as_thingy' to the top of the file that contained

class TestThingy
  include ActsAsThingy

  acts_as_thingy :name
end

I am not sure why Ruby didn't just throw an error when it couldn't find ActsAsThingy but it explains why the self.included method never got called (the include failed, but silently).

Dave Sag
  • 13,266
  • 14
  • 86
  • 134
-1

Check your scope. Check your file require path. Include is used for including methods into other

Modules

Require is what you want to use in your case.

Read up on the differences between require and include: What is the difference between include and require in Ruby?

Here is my test code for your problem.

class A
  require_relative 'test.rb'


end

p('test')


module Test

  def self.included(base)
    base.extend(ClassMethods)
  end

  module ClassMethods
    def p(str)
      print "#{str}"
    end
  end
end

output: vagrant [test]> ruby file.rb "test"

Community
  • 1
  • 1
powerup7
  • 120
  • 3
  • 14