`
Goldice
  • 浏览: 104717 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

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的值。

 

分享到:
评论

相关推荐

    Ruby面试题和答案(2024年收集更新)

    1、Ruby编程语言是什么? Ruby 是一种动态的、反射性的、通用的、开源的编程语言,专注于简单性和生产力。...Ruby 和 Python 相似之处: 高级语言支持多平台使用名为 irb 的交互式提示服务器端脚本

    Ruby基础知识之类

    创建类: class后跟...在c#中的域,在ruby中称为实例变量,定义时前边加@前缀,表示是一个实例变量。 代码如下: class Customer  def initialize(name,age)  @name,@age=name,age  end end   c1=Customer.

    Ruby 魔法 学习笔记之一

    一、向对象显示的发送... 不光如此send可以使程序更加动态,下面我们看看一个例子: 我们定义了一个类Person,我们希望一个包含Person对象的数组能够按 照Person的任意成员数据来排序: Ruby代码 代码如下:class Perso

    使用C++来编写Ruby程序扩展的教程

    Ruby 最酷的功能之一就是使用 C/C++ 定义的应用程序编程接口 (API) 扩展它。Ruby 提供了 C 头文件 ruby.h,它随附提供了许多功能,可使用这些功能创建 Ruby 类、模块和更多内容。除了头文件,Ruby 还提供了其他几个...

    state_machines:增加了对在任何Ruby类上为属性创建状态机的支持

    $ bundle或自己安装为: $ gem install state_machines用法例以下是此插件提供的许多功能的示例,包括: 初始状态命名空间状态过渡回调条件转换状态驱动的实例行为自定义状态值平行活动路径分析类定义: class ...

    pycall.rb:从Ruby语言调用Python函数

    请注意,在pycall.rb中,不完全支持在Python 2.7中定义的没有超类的旧类。 pyenv用户注意 pycall.rb需要Python的共享库(例如libpython3.7m.so )。 pyenv默认不构建共享库,因此您需要在安装时指定--enable-shared...

    Ruby基础知识之方法、代码段

    Ruby中的方法是一个有名称的代码块,是...在类中定义的方法为实例方法,实例方法可以在类的实例对象上使用。如果是在一个特定的对象上定义方法,那么此方法就是一个单键方法,只能在这个对象上使用。 代码如下: class

    在Ruby中查找和执行方法

    当调用一个方法时,Ruby会在对象的类中查找那个方法。不过,在给出更复杂的例子之前,你需要了解两个新概念:接收者(receiver)和祖先链(ancetors chain)。 接收者就是你调用方法所在的对象。例如,在my_

    详解Ruby设计模式编程中对单例模式的运用

    简介  单例模式是设计模式中最简单的形式之一。这一模式的目的是使得类的一个对象成为系统中的唯一... 从具体实现角度来说,就是以下三点:一是单例模式的类只提供私有的构造函数,二是类定义中含有一个该类的静态

    comma:逗号是Ruby对象的小型CSV(即逗号分隔值)生成扩展,可让您通过小型DSL无缝定义CSV输出格式

    一个为ActiveRecord和Array之类的Ruby对象生成逗号分隔值(CSV)的库 入门 先决条件 您需要使用ruby 2.4或更高版本。 如果从ActiveRecord模型生成CSV,则需要具有ActiveRecord 5.0或更高版本。 正在安装 逗号作为gem...

    Ruby的面向对象方式编程学习杂记

    class关键字的核心任务是把你带到类的上下文中,让你可以在里面定义方法。 每个类都是一个模块,类就是带有三个方法(new,allocate,superclass)的增强模块,通过这三个方法可以组织类的继承结构

    袍:Ruby的代码导航,文档查找和完成

    Robe是一个代码辅助工具,它使用Ruby REPL子进程加载了您的应用程序或gem代码,以提供有关已加载的类和模块以及定义每个方法的位置的信息。 通常,您需要从Mx inf-ruby-console-auto 。 如果没有运行Ruby控制台,...

    rubrowser:ruby代码依赖图交互式可视化器

    Ruby代码(轨道或其他代码)的可视化工具,它分析您的代码并提取模块定义和使用的类/模块,并使用D3将所有这些信息呈现为有向力图。 注意: 从2.0.0版本开始,该项目不再是http服务器,它会生成一个自包含HTML文件...

    kiba:用于Ruby的数据处理和ETL框架

    对于任何无法预料的问题和诸如安装问题之类的简单问题, 客户将获得优先的私人电子邮件支持。 我们的咨询服务也将优先于Kiba Pro订户。 如果您需要有关ETL和数据管道实施的任何指导,请我们联系,以便我们讨论如何...

    dice.js-ruby-007-public

    语言标签资源javascript 初学者,数字,OO 2个骰子在本实验中,您需要创建一个JavaScript构造函数。 该代码的框架已经放置在... Ruby认为实例方法的方法将在JavaScript中定义为原型的属性。 前任。 Dice . prototype .

    权限:*目前未维护*。 授权可以帮助您授权Rails应用程序中的操作。 它是ORM中立的,语法很少。 只需将模型分组到一个或多个Authorizer类下,并在其上编写普通的Ruby方法

    如果将它与Rails控制器一起使用,则它要求您的应用程序中已经有某种用户对象,可以通过current_user (可配置)之类的方法进行访问。内容 可以轻松实现) 单独的单点登录应用中的角色用户积分(如StackOverflow) ...

    耐嚼:基于官方elasticsearch-ruby客户端的高级Elasticsearch Ruby框架

    Chewy是一种ODM(对象文档映射器),建立在之上。 目录 为什么要耐嚼? 在本节中,我们将介绍为什么您可能要使用Chewy而不是Official elasticsearch-ruby客户gem。 多模型索引。 索引类独立于ORM / ODM模型。 ...

    在Ruby on Rails中优化ActiveRecord的方法

    通过 ActiveRecord,我只定义数据库模式:或者用 SQL 或者用称为迁移(migration)的 Ruby 类。将对象模型设计建立于数据库结构之上的那些框架称为包装框架。与大多数包装框架不同,Rails 能通过查询数据

    带有实体和存储库的Ruby持久性框架-Ruby开发

    该体系结构使业务逻辑(实体)与诸如持久性或验证之类的细节分离开来。 它实现了以下概念:实体-由其标识定义的模型域对象。 存储库-在实体和持久层之间进行中介的对象。 像所有其他Hanami组件一样,它可以用作sta

    ruby-metaprogramming-triangle-classification-lab

    三角分类实验室 ... 这个自定义错误类应该在同一个文件中被定义Triangle班,里面的Triangle类定义。 像这样: # lib/triangle.rb class Triangle # triangle code class TriangleError &lt; Standa

Global site tag (gtag.js) - Google Analytics