On Monday, October 3, 2011 at 9:00 AM, Gary Wright wrote:
> It isn't clear to me how this solves the scoping problem. Consider:
> 
> class Foo
>  String = String.except(A)
> 
>  s = "a string literal"
>  s.some_method_from_module_A  # NoMethodError ??
> end
> 
> How exactly is Ruby going to determine that the literal should be an instance of Foo::String rather than ::String? What if I call File.read within the class block? Will the returned string be a Foo::String? If so, how is File.read supposed to implement that?

 So, to answer your first point, string literals would still be instances of the top-level string class. If you wanted a string without A mixed in, you would do: 

 class Foo
 String = String.except(A)

 s = String.new("a string literal")
 end

As for the second question, File.read would still return a ::String.

Actually, I removed a final paragraph from my original proposal because I thought it might be a bit too confusing, but in this case I think it would actually make things clearer. In addition to Module#only, Module#except, Module#prefix, and Module#rename, I would also propose Binding#import which would allow one to inject a library form (Class/Module) into the binding of another library form, returning a new library form (essentially cloning the class and binding and dynamically injecting a new binding). This way, if you wanted File.read to return a String with module A excluded, you would do:

 class Foo
 myString = String.except(A)
 myFile = File.send(:binding).import(myString)
 #=> myFile will now create Strings excluding module A upon String.new
 def bar
 s = myFile.read('/path/to/file')
 s.some_method_from_module_A #=> NoMethodError
 end
 end

(Note that in this example I used myString and myFile to make the modifications clear, but assigning to String and File should have the same effect.) The biggest issue I can foresee with this proposal is that cloning a binding might get very costly. I think that in order for this part of my proposal to work, we would need to re-think the openness of bindings in Ruby (something that I have actively advocated for anyhow).

I should also say that to keep the code cleaner, I think I would actually prefer a Module#import instead of requiring the programmer to manually extract the binding and inject the new form, but the same underlying manipulations of module/class bindings would need to occur regardless.

Thanks for the feedback!

- Josh