Java guilt

Jos Backus schrieb:
>>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?

···

On Sat, Mar 17, 2007 at 01:45:03AM +0900, Pit Capitain wrote:

>On Thu, Mar 15, 2007 at 11:27:43AM +0900, David A. Black wrote:

Regards,
Pit

Great! Now I am feeling a bit better knowing that I am not the only one with
a case of Java guilt.

Being a Ruby newbie myself, I had mixed feelings of joy and disgust when I
saw a tutorial showing how Rails overrides string and numeric classes. I am
already at a stage of acceptance and rejoice now.

···

On 3/15/07, Luciano Ramalho <ramalho@gmail.com> wrote:

> Really though I'm growing more comfortable with the "patch everything"
> philosophy.

I'll borrow a quote from Alan Runyan (one of the creators of Plone),
which applies to Python and but even more so to Ruby:

"Ruby is a language for consenting adults."

s
Luciano

Good point, Pit. The String defined outside would not be effected.
Most data comes from the outside, so there's really no point to this
unless the incoming data is recast into the extended version
automatically (or manually?).

T.

···

On Mar 16, 12:49 pm, Pit Capitain <p...@capitain.de> wrote:

Trans schrieb:

> I wrote an experimental lib a while back that let you sub in your
> class for another within the scope of another module/or class. I think
> it's a pretty easy way to work with this concept. Far-sight better
> than the clock based approaches, IMO. The central idea is:

> class InBlanket

> # This would have a even nicer DSL.

> String = Class.new(::String) do
> def to_s; "(" + super + ")"
> end

> def tryme
> puts "three pigs"
> end

> end

> InBlanket.new.tryme #=> "(three pigs)

> This could actually be made to work fairly easily *if* literals used
> the ::new methods. Unfortunately they don't. So one would have to do
> back and use String.new instead of "". I consider this a design flaw
> in Ruby current implementation, though I'm sure there are
> justifications for it (probably execution speed related).

Tom, what would happen in your implementation if I pass a string from
the outside to tryme? And what would happen if I use a string created in
InBlanket outside of the class?

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.

···

On Mar 16, 9:23 pm, Logan Capaldo <logancapa...@gmail.com> 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?