ruby 元编程 meta programming

module A;end
module B; include A;
def hi; puts "Hello gays! enjoy Ruby! ";end; end
class C; include B; end

$f
= File.open("metaProgram.rb")
$lines
= $f.readlines

def p(a,no)
#$f.readline until $f.lineno == (no-1)
#puts "#{a}------>->->#{$f.readline}"

puts
"#{a}------>->->#{$lines[no-1]}"
end

p(C
< B,__LINE__)
p( B
< A,__LINE__)
p( C
< A,__LINE__)
p( Fixnum
< Integer,__LINE__)
p( Integer
< Comparable,__LINE__)
p( Integer
< Fixnum,__LINE__)
p( String
< Numeric,__LINE__)

p( A.ancestors,
__LINE__)
p( B.ancestors,
__LINE__)
p( C.ancestors,
__LINE__)
p( String.ancestors,
__LINE__)

p( C.include?(B),
__LINE__)
p( C.include?(A),
__LINE__)

p(A.
class,__LINE__)
#p(A.superclass,__LINE__)
p(B.class,__LINE__)
#p(B.superclass,__LINE__)
p(C.class,__LINE__)
p(C.superclass,
__LINE__)

p(A.included_modules,
__LINE__)
p(B.included_modules,
__LINE__)
p(C.included_modules,
__LINE__)

p(($f.instance_of? A),
__LINE__)
p(($f.instance_of? File),
__LINE__)

p(($f.kind_of? File),
__LINE__)
p(($f.is_a? File),
__LINE__)

#----------------extend-------------

#B.new.hi

s
= "String object "
s.extend(B)
p s.hi,
__LINE__

M
= Module.new{def mod
puts
"called from #{self.class} , defined in M.mod"
end
}

D
= Class.new{
def cl
puts
"called from #{self.class} , defined in D.cl"
end
}

E
= Class.new(D)\
{
include M

def hello
puts
"called from #{self.class} , defined in E.hello"
end
}

#D.new.mod
D.new.cl
E.new.mod
E.new.cl
E.new.hello

#--------------eval--------------
xa = 1
puts eval
"xa+1"

#-------------Binding--------------
class Object
def bindings
binding
end
end

class Test
def initialize(x)
@x
= x
end
end

t
= Test.new(10)
puts eval(
"@x",t.bindings) #oh! shit! you can pick the private member

#--------------------------------

t.instance_eval(
"@x")
String.class_eval(
"def len;size;end")
String.class_eval(
"alias len size")
String.instance_eval(
"def empty; ' ' ; end ")

s
= "how long is this" ;
puts s.len
#Noctice:class_eval() is for instance
puts s.size # I feel confused
puts "|#{String.empty}|" #Notice: instance_eval() is for Class

#-------------instance_exec/class_exec---------------


#----------var and Constrans------------
puts global_variables
x
=1
puts local_variables

#define a simple class
class Point
def initialize(x,y)
@x
=x
@y
= y
end
@@class_var
=1
ORIGIN
= Point.new(0,0)
end

p(Point::ORIGIN.instance_variables,
__LINE__)
p(Point::class_variables,
__LINE__)
p(Point::constants,
__LINE__)

p(
"s".method(:reverse),__LINE__)
p String.instance_method(:reverse),
__LINE__


p((
"hello".send :upcase),__LINE__)
p(Math.send(:sin,Math::PI
/2),__LINE__)

#the class_eval() is to use the private method ---define_method()
#
It is really powerful
String.class_eval{define_method(:greet,lambda{puts "hello"})}

"S".greet

  

输出如下:

true------>->->p(C < B,__LINE__)

true------>->->p( B < A,__LINE__)

true------>->->p( C < A,__LINE__)

true------>->->p( Fixnum < Integer,__LINE__)

true------>->->p( Integer < Comparable,__LINE__)

false------>->->p( Integer < Fixnum,__LINE__)

------>->->p( String < Numeric,__LINE__)

A------>->->p( A.ancestors,__LINE__)

BA------>->->p( B.ancestors,__LINE__)

CBAObjectKernel------>->->p( C.ancestors,__LINE__)

StringEnumerableComparableObjectKernel------>->->p( String.ancestors,__LINE__)

true------>->->p( C.include?(B),__LINE__)

true------>->->p( C.include?(A),__LINE__)

Module------>->->p(A.class,__LINE__)

Module------>->->p(B.class,__LINE__)

Class------>->->p(C.class,__LINE__)

Object------>->->p(C.superclass,__LINE__)

------>->->p(A.included_modules,__LINE__)

A------>->->p(B.included_modules,__LINE__)

BAKernel------>->->p(C.included_modules,__LINE__)

false------>->->p(($f.instance_of? A),__LINE__)

true------>->->p(($f.instance_of? File),__LINE__)

true------>->->p(($f.kind_of? File),__LINE__)

true------>->->p(($f.is_a? File),__LINE__)

Hello gays! enjoy Ruby! 

------>->->p s.hi,__LINE__

called from D , defined in D.cl

called from E , defined in  M.mod

called from E , defined in D.cl

called from E , defined in E.hello

2

10

16

16

|     |

$-w

$:

$.

$KCODE

$-F

$*

$stderr

$,

$`

$-p

$"

$$

$<

$@

$-v

$-i

$deferr

$\

$=

$;

$PROGRAM_NAME

$stdout

$&

$-d

$LOAD_PATH

$-a

$VERBOSE

$FILENAME

$defout

$-0

$+

$lines

$0

$stdin

$~

$DEBUG

$-I

$_

$-K

$>

$/

$'

$f

$-l

$LOADED_FEATURES

$?

$SAFE

$!

s

xa

t

x

@x@y------>->->p(Point::ORIGIN.instance_variables,__LINE__)

@@class_var------>->->p(Point::class_variables,__LINE__)

ORIGIN------>->->p(Point::constants,__LINE__)

#<Method: String#reverse>------>->->p( "s".method(:reverse),__LINE__)

#<UnboundMethod: String#reverse>------>->->p String.instance_method(:reverse),__LINE__

HELLO------>->->p(("hello".send :upcase),__LINE__)

1.0------>->->p(Math.send(:sin,Math::PI/2),__LINE__)

hello

posted @ 2011-08-16 00:42  fandyst  阅读(398)  评论(0编辑  收藏  举报