From: Trans Date: 2007-03-17T11:22:55+09:00 Subject: Re: java guilt On Mar 16, 9:23 pm, Logan Capaldo wrote: > On Sat, Mar 17, 2007 at 01:45:03AM +0900, Pit Capitain wrote: > > Jos Backus schrieb: > > >On Thu, Mar 15, 2007 at 11:27:43AM +0900, David A. Black wrote: > > >>As soon as someone figures out a way to make it work, all will be well > > >>:-) Actually the libraries that allow block-scoped core changes have > > >>never been widely used, as far as I can tell. > > > >Are you referring to libraries like `scope-in-state'? AfaIac, these don't > > >do > > >what I want them to do, which is the ability to restrict changes made to > > >some > > >class while executing code in some other class. This is probably expensive > > >as > > >hell and non-trivial to implement. But it sure would be great to have as it > > >would make Ruby a "safer" language. > > > Jos, we've talked about this two months ago on ruby-core. Maybe it's > > only the syntax of libraries like "import-module" which you don't like, > > but I think they can do what you want. See below. > > > >Imagine if you could add String#foo to be visible within class Bar only > > >without having to subclass String and use it inside of Bar instead of > > >String > > >(arguably the cleanest way to make this work otherwise). > > > Changing the interface of import-module to something like Tom's example, > > here's your use case: > > > require "import-module-extended" > > > class Bar > > > extending(String) do > > def foo > > "the foo version of #{self.inspect}" > > end > > end > > > def initialize(name) > > @name = name > > end > > > def hello(name = nil) > > name ||= @name > > puts(name.foo) > > end > > > end > > > b = Bar.new("Jos") > > b.hello # => the foo version of "Jos" > > b.hello("Pit") # => the foo version of "Pit" > > > b.hello(1) rescue puts "no Fixnum#foo" # => no Fixnum#foo > > "Pit".foo rescue puts "no String#foo" # => no String#foo > > > You can see that #foo is added to String but is only visible within > > class Bar. (The implementation is a quick and dirty hack, though.) > > What happens if I do > class Q > def initialize(s) > s.foo > end > end > > class Bar > def hello2 > Q.new("hmm") > end > end > > Bar.new.hello2 > > More importantly than what does happen, is what should happen? It should raise an error. #foo is not defined for String in the scope of Q. Which is why my idea doesn't work --at least not as I originally conceived it. Any efficient implementation of this becomes quite a problem I imagine. Seems like it would require all objects to be references, so they could become any other type on the fly. T.