Hello everyone,
I am currently playing around with Ruby 2.0. I wanted to look into
Refinements and here is what I came up with:
====
module RefinementTest
refine Hash do
def super_duper
"Hello World"
end
end
end
class MyTestClass
using RefinementTest
def initialize
puts {}.super_duper
end
end
MyTestClass.new
====
This is basically how it's described everywhere.
However when I run this code, I'll get that error:
====
[~]$ ruby refinements.rb
refinements.rb:2: warning: Refinements are experimental, and the
behavior may change in future versions of Ruby!
refinements.rb:10:in `<class:MyTestClass>': undefined method `using' for
MyTestClass:Class (NoMethodError)
from refinements.rb:9:in `<main>'
====
It only works when I move the 'using RefinementTest' one level up (in
the main namespace). But isn't that the same as monkeypatching the Hash
class in the first place?
Or am I doing something fundamentally wrong?
I used 2.0.0-rc1
on 2013-01-11 00:26
on 2013-01-11 02:14
Refinements were altered (pretty much at the last moment) to be *file* scoped. So that's why `using` only makes sense at toplevel.
on 2013-03-06 23:22
This is kind of a bummer. I have a gem that I'd like not to make
dependent on some other arbitrary gem(s). (Yes, I know rubygems is a
dependency manager.) In any case, to avoid pulling in all of
ActiveSupport, I implement my own flavor of Inflector. And I put a few
keen methods on String like String.singularize and String.pluralize...
All well and good until some other library with some other
implementation of these String extensions gets pulled in.
So using what I thought refinements would be, I could have done:
module CoreExtensions
class String
def singularize
# something here
end
end
end
class MyConsumerClass
using CoreExtensions
def do_something
puts "dogs".singularize
end
end
This would magically have scoped my String extensions to the
CoreExtensions module, preventing any namespace pollution, while at the
same time allowing include-like access to these extensions within my
class.
File scope is ok, but nowhere near as precise as module or class scoped
refinements.
Just my $.02.
on 2013-03-07 17:56
steve ross <cwdinfo@gmail.com> wrote: > end > This would magically have scoped my String extensions to the >CoreExtensions module, preventing any namespace pollution, while at the >same time allowing include-like access to these extensions within my >class. > But you can still do that: module CoreExtensions refine String do def singularize "howdy" end end end using CoreExtensions class MyConsumerClass def do_something puts "dogs".singularize end end MyConsumerClass.new.do_something That works because MyConsumerClass was defined *after* the "using" statement, so it gets the refinement of String. Nothing else does. "Some other library with some other implementation" does not. I missed the earlier discussion on this thread, though, so perhaps this isn't helpful... m.
Please log in before posting. Registration is free and takes only a minute.
Existing account
(Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
Log in with Google account | Log in with Yahoo account
No account? Register here.