(Ruby/Python/Perl)
Ruby 语言与Python和Perl的一个很大区别,在于Ruby中,所有的实例变量都是在类中完全私有的,只能通过accessor 方法来进行变量访问,引用一段代码来说明具体的使用方法:
class Rectangle attr_accessor :width attr_accessor :height attr_accessor :width2 attr_accessor :height2 def initialize(wdth, hgt) @width = wdth @height = hgt end def area() return @width * @height end def area2() return @width2 * @height2 end end r = Rectangle.new(2,3) r.width = 5 # give samename's variable value 给同名变量的变量赋值 r.height = 5 puts r.area() # outputs is 25 r.width2 = 6 # not samename's variable create 无同名变量的变量创建 r.height2 = 6 puts r.area2() # outputs is 36
attr_reader: 实例变量只读 attr_writer: 实例变量可写 attr_accessor: 变量可读可写
近来学习ruby的过程中,看到了拟态方法的概念,感觉很有意思。我们都知道拟态方法在ruby中无处不在,可以让代码更清爽更容易理解,比如
obj.my_attribute=""就不必写成obj.my_attribute=(""),而更进一步的,像attr_accessor这样的类宏的实现方式也引起了我的兴趣。
看了网上的实现方式,自己动手试了一下。
class Module def var( method_name ) inst_variable_name = "@#{method_name}".to_sym # .to_sym p inst_variable_name #:=>:@bar define_method method_name do instance_variable_get inst_variable_name end define_method "#{method_name}=" do |new_value| instance_variable_set inst_variable_name, new_value end end end class Foo var :bar end f = Foo.new # p f.bar p f.class #:=>Foo p f.class.instance_methods(false) #:=>["bar", "bar="] f.bar = "good" #:=>"good" method bar= p f.bar #:=>"good" method bar
上面的var方法就类似于attr_accessor,对其中的instance_variable_get用代码进行一下说明:
class Fred #attr_accessor :a #不要去掉注释,先直接运行 #attr_accessor :b def initialize(p1, p2) @a, @b = p1, p2 end end fred = Fred.new('cat', 99) puts fred.instance_variable_get(:@a) #=> "cat" puts fred.instance_variable_get("@b") #=> 99 #puts fred.a,fred.b,fred.a.class,fred.b.class =begin 上一句结果 cat 99 String Fixnum =end
我们都知道在ruby中:a等价于"a"但用前面的方法会更清爽,并且少写一个符号。