Ruby之类定义

介绍几种不常见的类定义方法:

 

1. Struct

 

Person=Struct.new(:name,:age,:sex)

p=Person.new("liyuchun")

puts p      

 

 Struct生成一个仅仅包含数据属性的类。但是你可以在这个类的基础上扩展:

 

Person=Struct.new(:name,:age,:sex)

class Person
        def log
                puts "log here"
        end
end

 

 ok,这样看上去并不是那么的cool,不是嘛。让我们稍微改一下:

 

class Person < Struct.new(:name,:age,:sex)
        def log
                puts "log here"
        end 
end

 

 it seems better. "<" 只要求后面跟着任何返回一个class object的表达式即可。

 

2. Class.new

我们是怎么定义一个类的?

 

class A
end

a = A.new

追根溯源,A是一个Class类的对象,而a是A类的对象。既然A通过new方法可以生成a,那么是否可以Class也可以通过new方法生成A呢?of course.

 

 

A = Class.new do
        def self.log
                puts "log here"
        end 

        def log
                puts "log there"
        end 
end

a=A.new
A.log
a.log

 

By default,新生成的类会继承自Object。But,if I want to change? Still easy : 

  A = Class.new(String) do ... end

此时,A就是继承自String类。

 

3. instance_eval和class_eval

何以解忧?唯有看代码。

 

class MyClass
end

MyClass.class_eval do
        def instance_method
                puts "In an instance method"
        end 
end

obj = MyClass.new
obj.instance_method

 然后

 

class MyClass
end

MyClass.instance_eval do
        def class_method
                puts "In a class method"
        end 
end

MyClass.class_method                        

class_eval生成的是实例方法,instance_eval生成的是类方法,何须多言啊,呵呵。

also,

 

animal = "cat"
"dog".instance_exec(animal) do |other|
          puts "#{other} and #{self}"
end

Ruby 1.9 引进了一些变种. Object#instance_exec, Module#class_exec和Module#module_exec使用instance_exec,你可以将参数传入block。

 

ok,我们可以利用class_eval实现attr_accessor的功能了:

 

module Mod
        def attr_reader1(*syms)  
               syms.each do |sym|  
                  class_eval %{
                            def #{sym}  
                                 @#{sym}  
                            end} 
                 end  
        end  
end  

class A
        extend Mod 
        attr_reader1 :name

        def initialize
                @name = "jinbin"
        end 
end

a=A.new
puts a.name

原来这里用的是include Mod,是不正确的。但是恰巧命名的函数为attr_reader,结果程序竟然也能运行通过,呵呵。ATTENTION!

 

这里使用了class_eval函数,出于对比,也用instance_eval来写了一个:

module Mod  
        def attr_reader(*syms)    
               syms.each do |sym|    
                  instance_eval %{  
                            def #{sym}    
                                @#{sym}
                            end}   
                 end    
        end    
end    
  
class A  
        extend Mod   
        attr_reader :name  

        @name = "jinbin"
  
        def initialize  
        end   
end  
  
puts A.name
由于class_eval生成的是实例方法,instance_eval生成的是类方法,所以调用上有所区别,在代码中都有体现。此处可以细细深究一下,注意self的值。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值