- 浏览: 1251430 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (729)
- Java_about (144)
- Spring_Hibernate_Struts_OpenSource (27)
- linux_unix (62)
- life_sth (21)
- js_css_html_xml_nodejs (69)
- design_pattens (1)
- Perl (8)
- php_ecshop (4)
- DB_Mysql_Oracle_Informix_SqlServer (43)
- JSTL (8)
- Testing_自动化测试 (42)
- DB_ID_UUID (4)
- SEM_SEO (1)
- english_study_improvement (4)
- SVN_Git (9)
- WebService_SOA_CloudComputing (3)
- E-Commerce (1)
- Lucene_Solr (7)
- others (2)
- Regex (2)
- tomcat_jetty (8)
- zeroc-ice (1)
- java_excel (5)
- ant_maven_gradle (5)
- Unity_VR_AR_C# (2)
- jmeter (1)
- XPath_dom4j (1)
- Ruby_and_Rails (68)
- write_a_rails (17)
- manage_and_team (1)
- getting_real (1)
- ubuntu (20)
- git_and_git_flow (7)
- TODO (1)
- PM_design (2)
- Python_and_Django (8)
- NoSql_mongo_redis (24)
- C/C++ (3)
- vi_vim_gvim (0)
- c#_.Net_windows编程_dll (10)
- Php_and_Yii (9)
- Android_IOS (31)
- Mysql (5)
- sa_运维_network_硬件 (37)
- lua (2)
- c_cpp_VisualStudio (21)
- 硬件-RM-Arduino (6)
最新评论
-
shenkun58:
...
NoClassDefFoundError: Could not initialize springframework.BeanCreationException -
liaojia1:
正解,感谢
NoClassDefFoundError: Could not initialize springframework.BeanCreationException -
flingfox63:
谢谢分享,电脑上有IPV6,导致了Guard启动不了……
ruby错误解决: Address family not supported by protocol - connect(2) -
c39274936:
s = "hello_world_ruby" ...
驼峰格式和下划线格式转换_translation between camel and snake format -
yfj300:
学习了学习了学习了学习了
硬盘基本知识(磁道、扇区、柱面、磁头数、簇、MBR、DBR)
简单来说,ruby中的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一直引用着它所在位置上下文的实例 (类也是一个实例)(其实这是跟java等一样的,合乎面向对象的要求,self/this指向自己) 。
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,就没有问题 了。
(另外,请注意,ruby中的实例变量要有@号,所以此处不用self,而用@name,也是可以的)
读到这,你是不是认为以后这种情况就一直用显式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 class << Person def method3 p 'method3' end private def method4 p 'method4' end end end m = Person.new #m.my_secret # => private method error Person.secret # => nothing Person.method3 #fantaxy added here! Person.method4 #fantaxy added here! #NoMethodError: private method `method4' called for Person:Class m.get_my_secret1 # => something m.get_my_secret2 # => private method error
上面代码说明:
第一个问题,显式self不可以调用private(protected的也一样)方法,而隐式的可以 (这个原因我在下面解释) 。
原因是什么?
self.my_secret # => 显式 #这一句的self在实例方法内,所以self指的是Person的一个实例,而实例是不能调用私有方法的(protected也如此) #注意,此时的self和我们new一个Person的实例没有本质区别。
第二个问题,本来:权限修饰符只对实例方法生效(下面解释) ,但是这里类方法也受限制了。
解释:
ruby中类也是一个实例,给类这个实例加入实例方法,也会有private/protected之分。
class << Person #给实例(Person)添加实例方法 def method3 p 'method3' end private def method4 p 'method4' end end
self“怪异”写法
下面代码被我个人称为怪异写法,因为平时用不到,但偶尔会看到,但看起来又不太直观,这里列举一下
class Person def metaclass class << self #这是ruby中单例的语法,其本质是生成一个self的单例类(虚类)|域 #因为上面的self在实例方法内,因此指的是Person的一个实例,所以会生成实例的单例类(不是类的单例类) #下面返回的self,是在单例类的作用域内,所以指的是其本身,即单例类本身(虚类) # 有些人比较迷惑,我打印出self是Person啊,这是由于ruby的实现问题,并不打印虚类本身, # 而是打印虚类的super类的类名,此处即Person类(X类的对象x,x的虚类的super指向X) 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
明白了self之后,看看下面的用法:ruby 的 extend self
我们想让实例方法同时为类方法,那么可以使用extend self,这个对于普通的类
可能没有什么用。但是对于module来说还是很有用的,因为module不可以实例化,
module的实例方法通过自身就无法单元测试,所以通过extend self可以作为类方法暴露
来测试了:
module M extend self def greeting puts "hi" end end
如果没有extend self,我们就无法使用M.greeting,
现在我们可以调用M.greeting了。
BTW:
module_function可以把module一个实例方法变成私有的,并复制一份放到其metaclass中。
参考:
http://ilstar.blogbus.com/logs/59782933.html
http://fuliang.iteye.com/blog/827443
评论
显式的调用类的私有方法,也是不行的。
但类的内部(也就是说隐式的调用)是可以的。我补充了一点。
Person.method4 #fantaxy added here! #NoMethodError: private method `method4' called for Person:Class
Thanks!
第一个问题,显式self不可以调用private(protected的也一样)方法,而隐式的可以 (这个原因我在下面解释) 。
原因是什么?
Ruby代码
self.my_secret # => 显式
#这一句的self在实例方法内,所以self指的是Person的一个实例,而实例是不能调用私有方法的(protected也如此)
#注意,此时的self和我们new一个Person的实例没有本质区别。
第二个问题,self的方法不受private限制,其实我在这故意误导了读者,因为self的方法是类方法,而权限修饰符只对实例方法生效(下面解释) ,所以 private的类方法也可以直接访问。 // 这个意思是, private修饰的实例方法不受限,而类方法受限吧?
发表评论
-
ruby计算平方和开方_n次方n次幂
2022-06-28 21:52 511= = = ruby计算平方和开方 3 ** 2#= ... -
Ruby发送HTTP请求
2015-07-21 18:06 1089Ruby使用HTTP协议发送请求的方法备忘。 好像这 ... -
invalid byte sequence in GBK”问题 invalid byte sequence in UTF-8”问题
2015-07-03 15:11 2730碰见错误: test.rb:8:in `ma ... -
Ruby1.9之字符串内编码和外编码
2015-07-02 17:52 1206这里的文章很不错的么:Rubyist http://ru ... -
DevKit介绍和安装in railsInstaller
2015-05-26 17:01 2570DevKit介绍和安装in railsInstaller ... -
Rails_migrations中使用mysql的bigint
2014-09-30 14:32 933From:http://rubyer.me/blog/468 ... -
Rails外如何启动rails的类自动加载_activates autoloading using ActiveSupport 3.x
2016-06-22 12:08 556The following cod ... -
如何在rails里打开gem里面的类_为何有时候不生效
2014-09-02 21:55 886在rails里面打开某个gem的类,补充一下等等,也 ... -
ruby的加载机制和rails_自动加载机制_对比
2014-09-02 16:51 1493prefer:http://urbanautomat ... -
Rails源码阅读(13)rails中的autoload和ruby的autoload
2014-07-30 17:13 1856Rails源码阅读(13)rails中的autoload和 ... -
Rails中命名路由的区别***_url与***_path
2014-07-29 16:37 1015Rails中命名路由的区别***_url与***_path ... -
ruby_gem安装_切换指定不同的源
2014-07-20 18:09 1094from:http://www.hiceon.com/to ... -
Ruby 的文件操作_不断总结
2014-07-11 11:55 1095一、用文件和目 ... -
Rails源码阅读(12)叫Rails的模块module_Rails常量使用
2014-07-02 09:35 993The module nams "Rail ... -
注册邮件中的链接无host
2014-05-19 14:47 584在注册邮件中用命名路由的xxx_url不起作用,导致注 ... -
每个命令都有bundle exec的麻烦
2014-04-18 17:33 1352问题: 每次都得搞这个东西bundle exec放在 ... -
关于favicon.ico的报错:RoutingError
2014-03-31 14:45 1865错误: ActionController::Routin ... -
rbenv_安装太慢_解决办法
2014-03-31 13:51 2095rvm做了很多“不为人知”的事情,而且做的太 ... -
配置sunspot tomcat结合sunspot_rails
2014-02-26 10:58 798这个sunspot的东西还是有不少缺点的。 ht ... -
RubyOrRails_使用技巧_收集
2013-11-09 14:39 1008#link_to not working in sc ...
相关推荐
Windows上配置Ruby运行环境详解
ruby-debug命令详解~~~~~~~~~~~~~~~~~~~~~
Ruby是一种优雅、灵活且强大的编程语言,它以其简洁的语法、丰富的功能和强大的扩展性,赢得了广大开发者的喜爱。本文将全面介绍Ruby编程语言的基本特点、应用场景、语法结构、常用库和框架,并通过具体实例展示Ruby...
而由于ruby作为一个完全纯净的面向对象语言,任何东东都是对象,方法是对象,类也是对象…,所以self就会有很多环境,区分不同环境的self含义才能更好的理解程序的含义 一、Top Level Context Ruby代码 puts self ...
ruby对excel的操作 详细描述ruby对excel的操作
如果你对万事万物的运行方式充满好奇,这本有趣的《R和Ruby数据分析之旅》会帮你找到日常生活中某些问题的真正答案。借助基本的数学方法,并使用Ruby和R语言做一些简单的编程工作,你就能学会如何对问题建模,并找出...
R和Ruby数据分析之旅 数据分析 数据挖掘
ruby on Rails程序设计深入剖析与范例应用(pdf+视频+源码)
[Ruby.Programming_向Ruby之父学程序设计(第2版)].(日)高桥征义,(日)后藤裕藏.扫描版(ED2000.COM).pdf ) 带书签
完整书名《Ruby Programming-向Ruby之父学程序设计》 ,就是那本经典的绿皮书 第一部分:通过简单的Ruby程序来介绍程序的基本架构。 第二部分:介绍基础语法规则,以及类、模块等面向对象程序设计的思考方法与...
ruby代码ruby代码ruby代码ruby代码ruby代码ruby代码ruby代码ruby代码
主要介绍了ruby 正则表达式详解及示例代码的相关资料,需要的朋友可以参考下
本章详细介绍Rails数据持久化技术ActiveRecord的使用,包括ORM与ActiveRecord的简介、建立数据表的映射、执行动态查询、插入数据、删除数据、表之间的关联,以及数据有效性验证等。 第11章 MVC的控制器层。本章...
整理后的在Ruby on rails的Haml有关render_partial的用法,本资源为一张图
ruby 目录操作详细介绍,增删查改,移动文件等等操作
Mail - 一个Ruby邮件库
《Ruby Programming:向Ruby之父学程序设计(第2版)》是为了让完全没有程序设计经验的读者也能灵活地使用Ruby,因此书中详细地说明了各种知识。从程序所需要的变量、常数、方法、类、控制结构等语法的说明,到类的主要...
本书是为了让完全没有程序设计经验的读者也能灵活地使用Ruby,因此书中详细地说明了各种知识。
《Ruby Programming_向Ruby之父学程序设计_第2版》PDF版本下载
Ruby+on+Rails+程序设计深入剖析与范例应用