This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
## Class#cattr
|
||||
|
||||
require 'facets/module/cattr'
|
||||
|
||||
class CAttrMockObject
|
||||
def initialize
|
||||
@@a = 10
|
||||
end
|
||||
def b ; @@b ; end
|
||||
end
|
||||
|
||||
Exception.refute.raised? do
|
||||
CAttrMockObject.class_eval{ cattr :a }
|
||||
end
|
||||
t = CAttrMockObject.new
|
||||
t.a.assert == 10
|
||||
|
||||
## Class#cattr_reader
|
||||
|
||||
Exception.refute.raised? do
|
||||
CAttrMockObject.class_eval { cattr_reader :a }
|
||||
end
|
||||
t = CAttrMockObject.new
|
||||
t.a.assert == 10
|
||||
|
||||
## Class#cattr_writer
|
||||
|
||||
Exception.refute.raised? do
|
||||
CAttrMockObject.class_eval { cattr_writer :b }
|
||||
end
|
||||
t = CAttrMockObject.new
|
||||
t.b = 5
|
||||
t.b.assert == 5
|
||||
|
||||
## Class#cattr_accessor
|
||||
|
||||
Exception.refute.raised? do
|
||||
CAttrMockObject.class_eval { cattr_accessor :c }
|
||||
end
|
||||
t = CAttrMockObject.new
|
||||
t.c = 50
|
||||
t.c.assert == 50
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
## Module#class_extend
|
||||
|
||||
require 'facets/module/class_extend'
|
||||
|
||||
Module using class_extend
|
||||
|
||||
mix = Module.new do
|
||||
def i ; end
|
||||
class_extend do
|
||||
def n ; 42 ; end
|
||||
def s ; self ; end
|
||||
end
|
||||
end
|
||||
|
||||
Extends module
|
||||
|
||||
mix.n.assert == 42
|
||||
mix.s.assert == mix
|
||||
|
||||
Has expected methods
|
||||
|
||||
mix.instance_methods.map{ |m| m.to_s }.assert == ['i']
|
||||
|
||||
transfers class methods to including class
|
||||
|
||||
mod = Module.new do
|
||||
include mix
|
||||
end
|
||||
mod.n.assert == 42
|
||||
mod.s.assert == mod
|
||||
|
||||
Doesn't overwrite instance methods
|
||||
|
||||
c = Class.new do
|
||||
include mix
|
||||
def n ; 11 ; end
|
||||
end
|
||||
c.new.n.assert == 11
|
||||
|
||||
Is overridable via including module
|
||||
|
||||
mod = Module.new do
|
||||
include mix
|
||||
class_extend do
|
||||
def n ; super + 1 ; end
|
||||
end
|
||||
end
|
||||
mod.n.assert == 43 # notice the difference!
|
||||
mod.s.assert == mod
|
||||
|
||||
Transfers class methods thru multiple levels of include
|
||||
|
||||
alt = Module.new do
|
||||
include mix
|
||||
class_extend do
|
||||
def n ; super + 1 ; end
|
||||
end
|
||||
end
|
||||
mod = Module.new do
|
||||
include alt
|
||||
end
|
||||
mod.n.assert == 43
|
||||
mod.s.assert == mod
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
## Module#class_inheritor
|
||||
|
||||
require 'facets/module/class_inheritor'
|
||||
|
||||
Subclass with inheritor
|
||||
|
||||
c = Class.new do
|
||||
class_inheritor :koko, [], :+
|
||||
koko! << 1
|
||||
end
|
||||
|
||||
d = Class.new(c) do
|
||||
class_inheritor :koko, [], :+
|
||||
koko! << 2
|
||||
end
|
||||
|
||||
We can see that
|
||||
|
||||
c.koko!.assert == [1]
|
||||
c.koko.assert == [1]
|
||||
|
||||
d.koko!.assert == [2]
|
||||
d.koko.assert == [1,2]
|
||||
|
||||
Subclass without class_inheritor
|
||||
|
||||
c = Class.new do
|
||||
class_inheritor :koko, [], :+
|
||||
koko! << 1
|
||||
end
|
||||
|
||||
d = Class.new(c)
|
||||
|
||||
Likewise
|
||||
|
||||
c.koko!.assert == [1]
|
||||
c.koko.assert == [1]
|
||||
|
||||
d.koko!.assert == []
|
||||
d.koko.assert == [1]
|
||||
|
||||
|
||||
Include module with class_inheritor
|
||||
|
||||
c = Class.new do
|
||||
class_inheritor :x, {}, :merge
|
||||
x![:a] = 1
|
||||
end
|
||||
|
||||
m = Module.new do
|
||||
class_inheritor :x, {}, :merge
|
||||
x![:b] = 2
|
||||
end
|
||||
|
||||
d = Class.new(c) do
|
||||
include m
|
||||
class_inheritor :x, {}, :merge
|
||||
x![:c] = 3
|
||||
end
|
||||
|
||||
Then
|
||||
|
||||
c.x.assert == {:a=>1}
|
||||
|
||||
m.x[:b].assert == 2
|
||||
|
||||
d.x.assert == {:a=>1,:b=>2,:c=>3}
|
||||
|
||||
c.x[:a].assert == 1
|
||||
c.x[:b].assert == nil
|
||||
c.x[:c].assert == nil
|
||||
|
||||
d.x[:a].assert == 1
|
||||
d.x[:b].assert == 2
|
||||
d.x[:c].assert == 3
|
||||
|
||||
And
|
||||
|
||||
d.x![:d] = 4
|
||||
d.x[:d].assert == 4
|
||||
|
||||
|
||||
Using #concat as the class_inheritor operator
|
||||
|
||||
c = Class.new do
|
||||
class_inheritor :relations, [], :concat
|
||||
end
|
||||
|
||||
d = Class.new(c) do
|
||||
#class_inheritor :relations, [], :concat
|
||||
end
|
||||
|
||||
c.relations! << 1
|
||||
c.relations! << 2
|
||||
d.relations! << 3
|
||||
|
||||
Notice
|
||||
|
||||
c.relations.assert == [1,2]
|
||||
d.relations.assert == [1,2,3]
|
||||
|
||||
|
||||
On Module
|
||||
|
||||
m = Module.new do
|
||||
class_inheritor :koko, [], :+
|
||||
koko! << 1
|
||||
end
|
||||
|
||||
c1 = Class.new do
|
||||
include m
|
||||
#class_inheritor :koko, [], :+
|
||||
koko! << 2
|
||||
koko! << 3
|
||||
end
|
||||
|
||||
c2 = Class.new do
|
||||
include m
|
||||
#class_inheritor :koko, [], :+
|
||||
koko! << 4
|
||||
end
|
||||
|
||||
m.koko.assert == [1]
|
||||
c1.koko.assert == [1,2,3]
|
||||
c2.koko.assert == [1,4]
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
## Module#copy_inheritor
|
||||
|
||||
require 'facets/module/copy_inheritor'
|
||||
|
||||
We see `#copy_inheritor` in action.
|
||||
|
||||
m = Module.new do
|
||||
copy_inheritor :koko, []
|
||||
koko << 1
|
||||
end
|
||||
|
||||
c1 = Class.new do
|
||||
include m
|
||||
#inheritor :koko, [], :+
|
||||
koko << 2
|
||||
koko << 3
|
||||
end
|
||||
|
||||
c2 = Class.new do
|
||||
include m
|
||||
#inheritor :koko, [], :+
|
||||
koko << 4
|
||||
end
|
||||
|
||||
And the result.
|
||||
|
||||
m.koko.assert == [1]
|
||||
c1.koko.assert == [1,2,3]
|
||||
c2.koko.assert == [1,4]
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
## Module#include_as
|
||||
|
||||
require 'facets/module/include_as'
|
||||
|
||||
Module#include_as utilizes #method_space to allow modules to be included
|
||||
within a separated namespace.
|
||||
|
||||
module T
|
||||
def t ; "Tt" ; end
|
||||
def r ; "Tr" ; end
|
||||
def q ; super ; end
|
||||
end
|
||||
|
||||
class N
|
||||
def q ; "Nq" ; end
|
||||
end
|
||||
|
||||
class X < N
|
||||
include_as :test => T
|
||||
|
||||
def n ; test.inspect ; end
|
||||
def m ; test.t ; end
|
||||
def o ; test.r ; end
|
||||
end
|
||||
|
||||
x = X.new
|
||||
|
||||
x.m.assert == "Tt"
|
||||
x.o.assert == "Tr"
|
||||
x.q.assert == "Nq"
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
## Module#method_space
|
||||
|
||||
require 'facets/module/method_space'
|
||||
|
||||
class A
|
||||
attr_writer :x
|
||||
method_space :inside do
|
||||
def x; @x; end
|
||||
end
|
||||
end
|
||||
|
||||
a = A.new
|
||||
a.x = 10
|
||||
|
||||
We can see that the `inside` method space has access to the instance space.
|
||||
|
||||
a.inside.x #=> 10
|
||||
|
||||
But there is no reader in the instance space.
|
||||
|
||||
expect NoMethodError do
|
||||
a.x
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user