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