From: Jos Backus Date: 2007-03-17T09:30:33+09:00 Subject: Re: java guilt 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. Indeed we did. > >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.) That's sweet! This does indeed seem to do what I'm looking for. Thanks Pit! And Tom, too. :-) If I wanted this to be used inside class Baz, too, would I stick `foo' in a module and use `extending' with that module somehow? I need to go check out `import-module-extended'... If it's a hacky implementation, how could it be cleaned up? This would be great to have as part of stdlib. Cheers, -- Jos Backus jos at catnook.com