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