Forum: Ruby-core class_extension

Posted by TRANS (Guest)
on 2007-03-23 10:05
(Received via mailing list)
I'm just following up to find out the status of consideration for
class_extension into Ruby 1.9/2.0. Is this going to make it in? Or
something like it?

Also I want to make a possible suggestion about it....

Of course, I still prefer the idea of an alternate to #include that
would mixin both the instance level and the singleton level. But...

A number of people I've talked don't care for the notation of
class_extension. I think they have a problem with the name and/or the
use of a block. It doesn't look like idiomatic Ruby. So I was thinking
that perhaps a better notation would be:

  module Foo

    class << extension
      ...
    end

  end

Where #extension is a Module method. This looks a good bit more
Rubyesque than the class_extension method. It would also allow for
this notation:

  module Foo

    def extension.bar
      "bar"
    end

  end

Which is pretty nice.

Thanks,
T.
Posted by Yukihiro Matsumoto (Guest)
on 2007-03-23 10:17
(Received via mailing list)
Hi,

In message "Re: class_extension"
    on Fri, 23 Mar 2007 18:03:47 +0900, TRANS <transfire@gmail.com> 
writes:

|A number of people I've talked don't care for the notation of
|class_extension. I think they have a problem with the name and/or the
|use of a block. It doesn't look like idiomatic Ruby. So I was thinking
|that perhaps a better notation would be:
|
|  module Foo
|
|    class << extension
|      ...
|    end
|
|  end
|
|Where #extension is a Module method. This looks a good bit more
|Rubyesque than the class_extension method.

I am not sure what class_extension or extension does.  Do they return
class/module themselves?

              matz.
Posted by TRANS (Guest)
on 2007-03-23 10:53
(Received via mailing list)
On 3/23/07, Yukihiro Matsumoto <matz@ruby-lang.org> wrote:

> I am not sure what class_extension or extension does.  Do they return
> class/module themselves?

You don't remember? It was your idea! Great, now I feel about this
('') small. I've been telling everyone I work with that
class_extension was being considered for inclusion into 1.9/2.0 b/c
that's what you indicated in the ruby-talk thread where this code came
into existence.

Well, I don't mean to blame. Lord, knows I forget things all the time.
So here's a complete reminder:

  ruby-talk:196402

It's a long thread however. In sum the resulting code (and
explanation) of what class_extension does follows.

Concerning #extension, yes it returns a special module used to achieve
the same ends.

T.


---

class Module

  alias_method :append_features_without_class_extension, 
:append_features

  # = class_extension
  #
  # Normally when including modules, class/module methods are not
  # extended. To achieve this behavior requires some clever
  # Ruby Karate. Instead class_extension provides an easy to use
  # and clean solution. Simply place the extending class methods
  # in a block of the special module method #class_extension.
  #
  #   module Mix
  #     def inst_meth
  #       puts 'inst_meth'
  #     end
  #
  #     class_extension do
  #       def class_meth
  #         "Class Method!"
  #       end
  #     end
  #   end
  #
  #   class X
  #     include Mix
  #   end
  #
  #   X.class_meth  #=> "Class Method!"
  #

  def class_extension(&block)
    @class_extension ||= Module.new do
      def self.append_features(mod)
        append_features_without_class_extension(mod)
      end
    end
    @class_extension.module_eval(&block) if block_given?
    @class_extension
  end

  private :class_extension

  def append_features(mod)
    append_features_without_class_extension(mod)
    mod.extend(class_extension)
    if mod.instance_of? Module
      mod.__send__(:class_extension).__send__(:include, class_extension)
    end
  end

end

class Class
  undef_method :class_extension
end



#  _____         _
# |_   _|__  ___| |_
#   | |/ _ \/ __| __|
#   | |  __/\__ \ |_
#   |_|\___||___/\__|
#

=begin test

  require 'test/unit'

  class TC_ClassMethods < Test::Unit::TestCase

    # fixture

    module N
      class_extension do
        def n ; 43 ; end
        def s ; self ; end
      end
      extend class_extension
    end

    class X
      include N
      def n ; 11 ; end
    end

    module K
      include N
      class_extension do
        def n ; super + 1 ; end
      end
    end

    class Z
      include K
    end

    # tests

    def test_01
      assert_equal( 43, N.n )
      assert_equal(  N,  N.s )
    end
    def test_02
      assert_equal( 43, X.n )
      assert_equal(  X, X.s )
    end
    def test_03
      assert_equal( 11, X.new.n )
    end
    def test_04
      assert_equal( 43, K.n )  #notic the difference!
      assert_equal(  K, K.s )
    end
    def test_05
      assert_equal( 44, Z.n )
      assert_equal(  Z, Z.s )
    end

  end

=end
Posted by Yukihiro Matsumoto (Guest)
on 2007-03-23 15:17
(Received via mailing list)
Hi,

In message "Re: class_extension"
    on Fri, 23 Mar 2007 18:51:56 +0900, TRANS <transfire@gmail.com> 
writes:

|> I am not sure what class_extension or extension does.  Do they return
|> class/module themselves?
|
|You don't remember? It was your idea!

As you might already know, my memory is volatile. ;-)

|It's a long thread however. In sum the resulting code (and
|explanation) of what class_extension does follows.

But this version does not work without block, as your previous
example.

              matz.
Posted by TRANS (Guest)
on 2007-03-24 17:28
(Received via mailing list)
On 3/23/07, Yukihiro Matsumoto <matz@ruby-lang.org> wrote:
> As you might already know, my memory is volatile. ;-)
>
> |It's a long thread however. In sum the resulting code (and
> |explanation) of what class_extension does follows.
>
> But this version does not work without block, as your previous
> example.

That's true. I was just suggesting an alternate notation that seemed
reasonable. But I haven't tried it and maybe it isn't sensible. I
guess we'd wind up with the same problem as before, now that  consider
it more, since a module's singleton isn't a module which is why it's
so difficult to reuse its methods.

T,
Posted by TRANS (Guest)
on 2007-04-01 02:38
(Received via mailing list)
On 3/23/07, Yukihiro Matsumoto <matz@ruby-lang.org> wrote:
> As you might already know, my memory is volatile. ;-)
Oh, I assure you, my memory is far worse!

But I am very curious to know what the future holds for Ruby in the
way of class-extension or like functionality.

Thanks,
T.
Please log in before posting. Registration is free and takes only a minute.
Existing account (Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
No account? Register here.