1.ruby类
以下多次定义,并不是定义了多个ClassName类,是同一个类
当第一次使用class Shape定义这个类的时候,这个类并不存在,因此直接定义;当二次定义同样类名的类时,这个类已经存在,不再重新定义,而是打开这个类,在其中定义新方法。
irb(main):024:0> class Shape
irb(main):025:1> def print_width
irb(main):026:2> p @width
irb(main):027:2> end
irb(main):028:1> def initialize(width,length)
irb(main):029:2> @width = width
irb(main):030:2> @length = length
irb(main):031:2> end
irb(main):032:1> end
=> nil
irb(main):033:0> class Shape
irb(main):034:1> def print_length
irb(main):035:2> p @length
irb(main):036:2> end
irb(main):037:1> end
=> nil
irb(main):038:0> shape = Shape.new(1,2)
=> #<Shape:0x1b5a5cf @width=1, @length=2>
irb(main):039:0> shape.print_length
2
=> nil
irb(main):041:0> shape.print_width
1
=> nil
irb(main):042:0>
2.类方法定义的方式:
class User
def self.p_basic_infor(name,age)
p "#{name},#{age}"
end
def User.say_hello(name)
p "#{name} say hello to you!"
end
class << self
def update_infor(name)
p "update the infor for #{name}"
end
end
end
User.p_basic_infor("tom",12)
User.say_hello("jack")
User.update_infor("Lily")
p User.singleton_methods
3.ruby实例变量
(1)只有给实例变量赋值的时候,实例变量才真正存在。
class User
def method
@v = 1
end
end
user_1 = User.new
p user_1.instance_variables #=〉[]
user_2 = User.new
user_2.method
p user_2.instance_variables #=〉[@v]
(2)类变量是实例层面的,方法是类层面的,因此类的不同实例可以共用同一个方法,但是不同的实例却不能共用同一个实例变量。类的不同实例不能共用同一个实例变量见下面例子:
user_1 = User.new
user_1.method
p user_1.instance_variables #["@v"]
user_2 = User.new
user_2.method
p user_1.instance_variables.equal?(user_2.instance_variables) #false
4.ruby作用域
ruby存在作用域的概念,出了某个作用域,变量的生命周期就结束了,常见的作用域门包括:class,def,module
冲破scope的方法是:
(1)使用Class.new代替class
(2)使用Module.new代替module
(3)使用define_method代替def
irb(main):001:0> name = "tom"
=> "tom"
irb(main):002:0> class User
irb(main):003:1> def p_name
irb(main):004:2> p "#{name} in the method"
irb(main):005:2> end
irb(main):006:1> end
=> nil
irb(main):007:0> user = User.new
=> #<User:0x1bb326c>
irb(main):008:0> user.p_name
NameError: undefined local variable or method `name' for #<User:0x1bb326c>
from (irb):4:in `p_name'
from (irb):8
irb(main):001:0> length = 1
=> 1
irb(main):002:0> Shape = Class.new do
irb(main):003:1* define_method :p_length do
irb(main):004:2* p "#{length} is in the method"
irb(main):005:2> end
irb(main):006:1> end
=> Shape
irb(main):007:0> Shape.new.p_length
"1 is in the method"
=> nil
irb(main):008:0>
5.ruby块
ruby块不是对象,使用Proc可以将块转为对象,将块转为Proc的方法包括:
#method_1
inc = Proc.new
inc.call(2)
#method_2
dec = lambda {|x| x-1}
dec.call(2)
#method_3
def match(a,b)
yield(a,b)
end
def do_match(a,b,&operation)
p match(a,b,&operation)
end
do_match(3,2) {|x,y| x*y}
相反的,也可以将Proc转为block
#convert Proc to block
def my_method(a,b)
p "#{yield(a,b)}"
end
my_proc = proc{|x,y| x+y}
my_method(1,2,&my_proc)
6.
(1)eigenclass是ruby的元类,是匿名类,在其中定义的方法称为Singleton Method
(2)打开eigenclass的方法有两种:
class User
def print_inf
p "user method"
end
class << self #open eigenclass
def say_hello #define Singleton Method
p "hello"
end
end
def User.hello(name) #define Singleton Method
p "hello, #{name}"
end
class << User #open eigenclass
def say_goodbye #define Singleton Method
p "goodbye"
end
end
def self.say_hi
p "hi"
end
end
p User.singleton_methods