[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Re: RubyTraits 0.1

Yukihiro Matsumoto

10/15/2007 3:12:00 PM

Hi,

In message "Re: RubyTraits 0.1"
on Mon, 15 Oct 2007 23:39:24 +0900, Trans <transfire@gmail.com> writes:

|> Even though I like the concept of traits, traits and modules are too
|> close in concept, too different in behavior. Having both in a
|> language may cause confusion. Too bad I didn't know about traits when
|> I designed Ruby.
|
|What behavior difference are you thinking about? To the end-programmer
|wouldn't it look mostly the same?

Yes, that's why I said "too close" to have them both.

The biggest difference I concern is traits inject attributes where
modules create relationship. Modules can conflict (overriding rule
applied), traits can't.

If I knew traits before designing Ruby, I'd have chosen traits over
modules. But that's the life.

matz.

2 Answers

Trans

10/15/2007 3:24:00 PM

0



On Oct 15, 8:11 am, Yukihiro Matsumoto <m...@ruby-lang.org> wrote:
> Hi,
>
> In message "Re: RubyTraits 0.1"
> on Mon, 15 Oct 2007 23:39:24 +0900, Trans <transf...@gmail.com> writes:
>
> |> Even though I like the concept of traits, traits and modules are too
> |> close in concept, too different in behavior. Having both in a
> |> language may cause confusion. Too bad I didn't know about traits when
> |> I designed Ruby.
> |
> |What behavior difference are you thinking about? To the end-programmer
> |wouldn't it look mostly the same?
>
> Yes, that's why I said "too close" to have them both.
>
> The biggest difference I concern is traits inject attributes where
> modules create relationship. Modules can conflict (overriding rule
> applied), traits can't.
>
> If I knew traits before designing Ruby, I'd have chosen traits over
> modules. But that's the life.

I see. So you don't really like the fact that modules fit into the
inheritance chain? That's interesting. The traits lib I wrote for
Facets actually uses the inheritance. Eg:

class Module

def +( other )
mod1 = other.clone
mod2 = clone
mod1.module_eval{ include mod2 }
return mod1
end

So instead of injection there's relationship, but in every other
respect its like traits. Is that not a good Ruby-esque way to do
traits? Maybe even better than injection actually?

T.


Trans

10/17/2007 12:48:00 PM

0

On Oct 15, 8:11 am, Yukihiro Matsumoto <m...@ruby-lang.org> wrote:

> If I knew traits before designing Ruby, I'd have chosen traits over
> modules. But that's the life.

I have to agree that traits are too much alike and yet too different
from modules to co-exist in the same language. However, I disagree
with this subsequent statement. Much of the benefit of traits can
still be had by overlaying the same concepts on Ruby's modules. In the
end I think the most important part is usability, not so much the
underlying implementation (as long as it is reasonably efficient, of
course). Moreover, I contend that if you are serious when you say, you
would have used traits instead of modules if he had known about them,
then you were fortunate not to have known, b/c modules are a more
powerful composition mechanism, despite their greater implementation
complexity.

To demonstrate my point here is Facets' module/traits.rb lib. I
improved it a fair bit yesterday --thanks to Robert and this thread.
I'd like others to have a look and provide any feedback. As you will
see in the code, I still have a couple questions about where to use
public vs. all instance methods (which leads me to question/thought
that I will bring up in another thread). Here you go...

class Module

# Combine modules.

def +(other)
base = self
Module.new do
include base
include other
end
end

# Subtract modules.
#--
# TODO Should this use all instance_methods, not just public?
#++
def -(other)
case other
when Array
subtract = instance_methods(true) & other.collect{|m| m.to_s}
when Module
subtract = instance_methods(true) &
other.instance_methods(true) # false?
when String, Symbol
subtract = instance_methods(true) & [other.to_s]
end
base = self
Module.new do
include base
subtract.each{ |x| undef_method x }
end
end

# Rename methods.

def *(rename_map)
base = self
Module.new do
include base
rename_map.each do |from, to|
alias_method to, from
undef_method from
end
end
end

# Detect conflicts.
#--
# TODO All instance methods, or just public?
#++
def conflict?(other)
c = []
c += (public_instance_methods(true) &
other.public_instance_methods(true))
c += (private_instance_methods(true) &
other.private_instance_methods(true))
c += (protected_instance_methods(true) &
other.protected_instance_methods(true))
c.empty ? false : c
end

#def conflict?(other)
# c = instance_methods & other.instance_methods
# c.empty ? false : c
#end

def public_conflict?(other)
c = public_instance_methods(true) &
other.public_instance_methods(true)
c.empty ? false : c
end

def private_conflict?(other)
c = private_instance_methods(true) &
other.private_instance_methods(true)
c.empty ? false : c
end

def protected_conflict?(other)
c = protected_instance_methods(true) &
other.protected_instance_methods(true)
c.empty ? false : c
end

end


Thanks,
T.