Skip to content

Commit

Permalink
bug squash session with module extensions
Browse files Browse the repository at this point in the history
  • Loading branch information
trans committed Jul 9, 2010
1 parent b006939 commit 2db427b
Show file tree
Hide file tree
Showing 30 changed files with 335 additions and 170 deletions.
18 changes: 9 additions & 9 deletions lib/core/facets/class/descendants.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,27 @@ class Class

# List all descedents of this class.
#
# class X ; end
# class A < X; end
# class B < X; end
# X.descendents #=> [A,B]
# class A ; end
# class B < A; end
# class C < A; end
# A.descendants #=> [B,C]
#
# You may also limit the generational distance the subclass may be from
# the parent class.
#
# class X ; end
# class A < X; end
# class B < A; end
# X.descendents #=> [A, B]
# X.descendents(1) #=> [A]
# class Y < X; end
# class Z < Y; end
# X.descendants #=> [Y,Z]
# X.descendants(1) #=> [Y]
#
# NOTE: This is a intensive operation. Do not expect it to be very fast.

def descendants(generations=-1)
descendants = []
subclasses.each do |k|
descendants << k
if generations != 0
if generations != 1
descendants.concat(k.descendants(generations - 1))
end
end
Expand Down
7 changes: 6 additions & 1 deletion lib/core/facets/class/methodize.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@ class Class

# Translate a class name to a suitable method name.
#
# My::CoolClass.methodize => "my__cool_class"
# module ::Example
# class MethodizeExample
# end
# end
#
# Example::MethodizeExample.methodize #=> "example__methodize_example"
#
def methodize
name.methodize
Expand Down
7 changes: 6 additions & 1 deletion lib/core/facets/class/pathize.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@ class Class

# Converts a class name to a unix path.
#
# My::CoolClass.pathize #=> "my/cool_class"
# module ::Example
# class PathizeExample
# end
# end
#
# Example::PathizeExample.pathize #=> "example/pathize_example"
#
def pathize
name.pathize
Expand Down
7 changes: 3 additions & 4 deletions lib/core/facets/class/subclasses.rb
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
class Class

# Rubinius
if defined?(Class.__subclasses__)
if defined?(Class.__subclasses__) # Rubinius

# Returns an array with the direct children of +self+.
#
# Integer.subclasses # => [Bignum, Fixnum]
# Integer.subclasses # => [Fixnum, Bignum]
#
alias_method :subclasses, :__subclasses__

else

# Returns an array with the direct children of +self+.
#
# Integer.subclasses # => [Bignum, Fixnum]
# Integer.subclasses # => [Fixnum, Bignum]
#
def subclasses
list = []
Expand Down
5 changes: 4 additions & 1 deletion lib/core/facets/class/to_proc.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,14 @@ class Class
# end
# end
#
# %w(john bob jane hans).map(&Person) => [john, bob, jane, hans]
# persons = %w(john bob jane hans).map(&Person)
#
# persons.map{ |p| p.inspect } #=> ['john', 'bob', 'jane', 'hans']
#
# CREDIT: Daniel Schierbeck
def to_proc
proc{|*args| new(*args)}
end

end

9 changes: 6 additions & 3 deletions lib/core/facets/module/abstract.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@ class Module
# Create an abstract method. If it is not overridden, it will
# raise a TypeError when called.
#
# class C
# class AbstractExample
# abstract :a
# end
#
# c = C.new
# c.a #=> Error: undefined abstraction #a
# c = AbstractExample.new
#
# expect TypeError do
# c.a
# end
#
# CREDIT: Trans

Expand Down
26 changes: 22 additions & 4 deletions lib/core/facets/module/alias_method_chain.rb
Original file line number Diff line number Diff line change
@@ -1,21 +1,39 @@
class Module

# Encapsulates the common pattern of:
# Encapsulates the common pattern of ...
#
# alias_method :foo_without_feature, :foo
# alias_method :foo, :foo_with_feature
#
# With this, you simply do:
# With this, you simply do ...
#
# alias_method_chain :foo, :feature
#
# For example
#
# class AliasMethodChainExample
# def foo
# "foo"
# end
#
# def foo_with_feature
# "foo!"
# end
#
# alias_method_chain :foo, :feature
# end
#
# And both aliases are set up for you.
#
# Query and bang methods (foo?, foo!) keep the same punctuation:
# example = AliasMethodChainExample.new
# example.foo #=> "foo!"
# example.foo_without_feature #=> "foo"
#
# Query and bang methods (foo?, foo!) keep the same punctuation ...
#
# alias_method_chain :foo?, :feature
#
# is equivalent to
# is equivalent to ...
#
# alias_method :foo_without_feature?, :foo?
# alias_method :foo?, :foo_with_feature?
Expand Down
8 changes: 4 additions & 4 deletions lib/core/facets/module/alias_module_function.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,20 @@ class Module
# a module function. The typical #alias_method
# does not do this.
#
# module Demo
# module AliasExample
# module_function
# def hello
# "Hello"
# end
# end
#
# Demo.hello #=> Hello
# AliasExample.hello #=> 'Hello'
#
# module Demo
# module AliasExample
# alias_module_function( :hi , :hello )
# end
#
# Demo.hi #=> Hello
# AliasExample.hi #=> 'Hello'
#
def alias_module_function(new, old)
alias_method(new, old)
Expand Down
12 changes: 6 additions & 6 deletions lib/core/facets/module/basename.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,20 @@ class Module

# Returns the root name of the module/class.
#
# module Example
# class Demo
# module ::BaseName
# class Example
# end
# end
#
# Demo.name #=> "Example::Demo"
# Demo.basename #=> "Demo"
# BaseName::Example.name #=> "BaseName::Example"
# BaseName::Example.basename #=> "Example"
#
# For anonymous modules this will provide a basename
# based on Module#inspect.
#
# m = Module.new
# m.inspect #=> "#<Module:0xb7bb0434>"
# m.basename #=> "Module_0xb7bb0434"
# m.inspect # "#<Module:0xb7bb0434>"
# m.basename # "Module_0xb7bb0434"
#
# CREDIT: Trans

Expand Down
10 changes: 8 additions & 2 deletions lib/core/facets/module/can.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,16 @@ class Module

# An alias for #extend.
#
# class X
# can Forwardable
# module EgCan
# def foo; "foo"; end
# end
#
# class EgCanClass
# can EgCan
# end
#
# EgCanClass.foo #=> 'foo'
#
# BTW, why is Forwardable an -able? It's not a mixin!

alias_method :can, :extend
Expand Down
49 changes: 31 additions & 18 deletions lib/core/facets/module/conflict.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,21 @@ class Module

# Detect conflicts.
#
# module A
# def c; end
# end
# module ConflictExample
#
# module B
# def c; end
# end
# module A
# def c; end
# end
#
# A.conflict?(B) #=> ["c"]
# module B
# def c; end
# end
#
# A.conflict?(B) #=> ["c"]
#
# TODO: All instance methods, or just public?
# end
#
# TODO: All instance methods, or just public?
#
# CREDIT: Thomas Sawyer, Robert Dober

Expand All @@ -23,38 +26,48 @@ def conflict?(other)
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 -= common_ancestor.public_instance_methods(true)
c -= common_ancestor.private_instance_methods(true)
c -= common_ancestor.protected_instance_methods(true)
if common_ancestor
c -= common_ancestor.public_instance_methods(true)
c -= common_ancestor.private_instance_methods(true)
c -= common_ancestor.protected_instance_methods(true)
end
c.empty? ? false : c
end

#def conflict?(other)
# c = instance_methods & other.instance_methods
# c.empty ? false : c
#end
# Should conflict? just be public methods? ...
#
# def conflict?(other)
# c = instance_methods & other.instance_methods
# c.empty ? false : c
# end

# Like #conflict?, but checks only public methods.
def public_conflict?(other)
common_ancestor = (ancestors & other.ancestors).first
c = public_instance_methods(true) & other.public_instance_methods(true)
c -= common_ancestor.public_instance_methods(true)
if common_ancestor
c -= common_ancestor.public_instance_methods(true)
end
c.empty? ? false : c
end

# Like #conflict?, but checks only private methods.
def private_conflict?(other)
common_ancestor = (ancestors & other.ancestors).first
c = private_instance_methods(true) & other.private_instance_methods(true)
c -= common_ancestor.private_instance_methods(true)
if common_ancestor
c -= common_ancestor.private_instance_methods(true)
end
c.empty? ? false : c
end

# Like #conflict?, but checks only protected methods.
def protected_conflict?(other)
common_ancestor = (ancestors & other.ancestors).first
c = protected_instance_methods(true) & other.protected_instance_methods(true)
c -= common_ancestor.protected_instance_methods(true)
if common_ancestor
c -= common_ancestor.protected_instance_methods(true)
end
c.empty? ? false : c
end

Expand Down
5 changes: 3 additions & 2 deletions lib/core/facets/module/instance_method.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@ class Module

# Access method as a singleton object and retain state.
#
# module K
# module ::K
# def hello
# puts "Hello World!"
# end
# end
# p K.instance_method!(:hello) #=> <UnboundMethod: #hello>
#
# K.instance_method!(:hello).inspect #=> "#<UnboundMethod: K#hello>"
#
# NOTE: This is limited to the scope of the current module/class.

Expand Down
49 changes: 48 additions & 1 deletion lib/core/facets/module/integrate.rb
Original file line number Diff line number Diff line change
@@ -1,2 +1,49 @@
require 'facets/module/revise'
require 'facets/module/redirect_method'
require 'facets/module/redefine_method'
require 'facets/module/rename_method'
require 'facets/module/wrap_method'
require 'facets/module/nodef'

class Module

# Using integrate is just like using include except the
# module included is a reconstruction of the one given
# altered by the commands given in the block.
#
# Convenient commands available are: #rename, #redef,
# #remove, #nodef and #wrap. But any module method
# can be used.
#
# module IntegrateExampleModule
# def q ; "q" ; end
# def y ; "y" ; end
# end
#
# class InegrateExampleClass
# integrate IntegrateExampleModule do
# undef_method :y
# end
# end
#
# x = InegrateExampleClass.new
# x.q #=> "q"
#
# expect NameError do
# x.y
# end
#
# This is like #revisal, but #revisal only
# returns the reconstructred module. It does not
# include it.
#
# CREDIT: Trans

def integrate(mod, &block)
#include mod.revisal( &blk )
m = Module.new{ include mod }
m.class_eval(&block)
include m
end

end

Loading

0 comments on commit 2db427b

Please sign in to comment.