This post originated from an RSS feed registered with Ruby Buzz
by Daniel Berger.
Original Post: More on traits (roles, whatever)
Feed Title: Testing 1,2,3...
Feed URL: http://djberg96.livejournal.com/data/rss
Feed Description: A blog on Ruby and other stuff.
Curtis took me to task regarding my mixins comment. Fair enough. So, what's a Ruby programmer to do to ensure that name collision doesn't happen? Let's review the options (which I'm putting here for my own sake as well as yours).
Option 1 - Use the use package (on the RAA). Rather than doing a wholesale include of a module, only include the methods you know you're going to need.
require "use"
class Foo
use Bar, :hello
end
Option 2 - Use the import-module package (on the RAA) and explicitly specify which module's method you want to use. It's a bit verbose but it works.
require "import-module"
f = Foo.new
# Use the Bar module's hello method
Foo.import_module(Bar) do
f.hello
end
# Use the Baz module's hello method
Foo.import_module(Baz) do
f.hello
end
Option 3 - Create a facade using module functions in your code. Naturally this assumes that module functions are available, though it's easy enough to make them if not.
class Foo
include Bar
include Baz
def hello
Bar.hello
end
end
Option 4 - Alias the desired methods before performing additional includes.
class Foo
include Bar
alias :hello_orig :hello
include Baz
end
f = Foo.new
f.hello # Baz's hello
f.hello_orig # Bar's hello
Although roles/traits can potentially be useful, I still don't believe that adding them into the Ruby core is needed or desireable. We have some 3rd party solutions, plus some potential builtin solutions if you really need them.
One thing I *would* agree to, however, is to make -w emit a method redefinition warning of some sort when module method conflicts do arise. I'm actually a little surprise it doesn't already, actually, though I'm not sure how difficult it would be to implement. Time to send an email to the list. :)