Ruby学习_self-阿里云开发者社区

开发者社区> 贺满> 正文

Ruby学习_self

简介: self上下文      Ruby的self有和Java的this相似之处,但又大不相同。Java的方法都是在实例方法中引用,所以this一般都是指向当前对象的。而Ruby的代码逐行执行,所以在不同的上下文(context)self就有了不同的含义,先来看看常见的context self都代表哪些...
+关注继续查看

self上下文

     Ruby的self有和Java的this相似之处,但又大不相同。Java的方法都是在实例方法中引用,所以this一般都是指向当前对象的。而Ruby的代码逐行执行,所以在不同的上下文(context)self就有了不同的含义,先来看看常见的context self都代表哪些

# 这个位置位于top level context,代表Object的默认对象main
p self # => main
p self.class # => Object
@self1 = self

# 因为所有自定义类都位于main context之中,所以这是Object的实例方法
# 同时也可以说是一个全局方法
def a_method
  @self2 = self
  p self
  # => main,因为有了实例变量@self1和@self2,所以打印出来的不是main这个字符
  # => 但仍然是main对象,注释掉4,8行即可看到效果
  p @self1 == @self2 # => true
end


# 下面是一个关于类中不同上下文的self
class Person
  p self # => Person,代表当前类
 
  def instance_method
    p self # => #<Person:0xb7818fdc>,代表当前类的实例
  end
 
  def self.class_method
    p self # => Person,和第16行一样代表当前类(这是类方法的context),它们是相等的
  end
end

m = Person.new
def m.hello
  p self # => 代表m这个单例对象
end

m.hello

 

    上面只写了在类中的self,其实在module也是一样的。通过上面代码你可以发现,self一直引用着它所在位置上下文的实例/类。

    self显式/隐式

    你可以先试着运行下面代码,看看有什么意外发生没有


 class Person
  attr_accessor :name
 
  def set_name(your_name)
    name = your_name
  end
end

m = Person.new
p m.name
m.set_name('today')
p m.name # => 猜是什么

 

    如果你猜是today就大错特错了,答案是nil,为什么是nil呢,在第5行,我明明调用的是attr_accessor生成的name=方法赋值的啊,你可以在前面加上self试试,代码如你预期的一样执行了。在这种情况下name = your_name并没有去调用attr_accessor生成的xx=方法,而是将name当作了一个局部变量,如果显式的指定self,就没有问题了。

    读到这,你是不是认为以后这种情况就一直用显式self去调用就好了,其实不然,下面的代码仍会说明一些问题


 class Person

  public
  def get_my_secret1
    my_secret # => 隐式
  end
 
  def get_my_secret2
    self.my_secret # => 显式
  end

  private
  def my_secret
    p 'something...'
  end
 
  def self.secret
    p 'nothing'
  end
end

m = Person.new
#m.my_secret # => private method error
Person.secret # => nothing
m.get_my_secret1 # => something
m.get_my_secret2 # => private method error
 

    上面代码说明:

    第一个问题,显式self不可以调用private(protected的也一样)方法,而隐式的可以,这说明隐式更具有灵活性,但由于上面隐式调用也同时存在一定的“误解”,所以读者应该明白他们之间的区别,以便更好的使用。

    第二个问题,self的方法不受private限制,其实我在这故意误导了读者,因为self的方法是类方法,而权限修饰符只对实例方法生效,所以private的类方法也可以直接访问。

    self“怪异”写法

    下面代码被我个人称为怪异写法,因为平时用不到,但偶尔会看到,但看起来又不太直观,这里列举一下

 class Person
  def metaclass
    class << self
      self
    end
  end
 
  def metaclass2
    self
  end
end

a = Person.new

b = a.metaclass
c = a.metaclass2

# 首先要明白,类Person是Class的一个“实例”,a是Person的一个实例
# 这里b也是一个Person类,但它是独一无二的,即你修改Person不会影响到b,反之亦然
p b # => #<Class:#<Person:0xb76f3800>>
p b.class # => Class

class Person
  def hello
    p 'hello Person'
  end
end

class << b
  def hello
    p 'hello b'
  end
end

b.hello # => hello b


p c # => #<Person:0xb76f3800>
p c.class # => Person

c.hello # => hello Person
 

    还有一个

 class Person
  def self.hello
    p 'hello'
  end
 
  class << self
    # 看了最上面self和context的关系,你应该知道这个self代表是Person类
    # 在这里为Person添加方法,其实也就是为Person添加类方法,和上面的self.hello异曲同工
    def work
      p 'hard work'
    end
  end
end

Person.work

 

 

转自:http://ilstar.blogbus.com/logs/59782933.html
 

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
阿里云服务器怎么设置密码?怎么停机?怎么重启服务器?
如果在创建实例时没有设置密码,或者密码丢失,您可以在控制台上重新设置实例的登录密码。本文仅描述如何在 ECS 管理控制台上修改实例登录密码。
4146 0
阿里云服务器端口号设置
阿里云服务器初级使用者可能面临的问题之一. 使用tomcat或者其他服务器软件设置端口号后,比如 一些不是默认的, mysql的 3306, mssql的1433,有时候打不开网页, 原因是没有在ecs安全组去设置这个端口号. 解决: 点击ecs下网络和安全下的安全组 在弹出的安全组中,如果没有就新建安全组,然后点击配置规则 最后如上图点击添加...或快速创建.   have fun!  将编程看作是一门艺术,而不单单是个技术。
4617 0
《“笨办法”学Ruby》(第3版)—习题2 注释和#号
程序里的注释是很重要的。它们可以用自然语言告诉你某段代码的功能是什么。想要临时移除一段代码时,你也可以用注释的方式临时禁用这段代码。这个习题就是让你学会在Ruby中使用注释。
1438 0
Ruby On Rails学习笔记(3)——Rails程序由0到1
     正如Rails的理念一样,创建一个新的Rails应用程序的过程非常简单,下面就来看看如何从0到1建立一个全新的Rails应用程序。     1、启动InstantRails,打开其Rails应用程序管理器(Rails Application Manager):         2、创建...
642 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,阿里云优惠总结大概有三种登录方式: 登录到ECS云服务器控制台 在ECS云服务器控制台用户可以更改密码、更换系.
5838 0
阿里云ECS云服务器初始化设置教程方法
阿里云ECS云服务器初始化是指将云服务器系统恢复到最初状态的过程,阿里云的服务器初始化是通过更换系统盘来实现的,是免费的,阿里云百科网分享服务器初始化教程: 服务器初始化教程方法 本文的服务器初始化是指将ECS云服务器系统恢复到最初状态,服务器中的数据也会被清空,所以初始化之前一定要先备份好。
10784 0
+关注
贺满
1、7年+测试经险,其中5年+金融(银行)领域业务经验,丰富的app\web\服务端测试经验. 2、4+年管理经验,有多次从0组建测试团队的经历,最多带过20+人的测试团队。
172
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
文娱运维技术
立即下载
《SaaS模式云原生数据仓库应用场景实践》
立即下载
《看见新力量:二》电子书
立即下载