- 浏览: 1241191 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (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 493= = = ruby计算平方和开方 3 ** 2#= ... -
Ruby发送HTTP请求
2015-07-21 18:06 1074Ruby使用HTTP协议发送请求的方法备忘。 好像这 ... -
invalid byte sequence in GBK”问题 invalid byte sequence in UTF-8”问题
2015-07-03 15:11 2699碰见错误: test.rb:8:in `ma ... -
Ruby1.9之字符串内编码和外编码
2015-07-02 17:52 1192这里的文章很不错的么:Rubyist http://ru ... -
DevKit介绍和安装in railsInstaller
2015-05-26 17:01 2560DevKit介绍和安装in railsInstaller ... -
Rails_migrations中使用mysql的bigint
2014-09-30 14:32 916From:http://rubyer.me/blog/468 ... -
Rails外如何启动rails的类自动加载_activates autoloading using ActiveSupport 3.x
2016-06-22 12:08 544The following cod ... -
如何在rails里打开gem里面的类_为何有时候不生效
2014-09-02 21:55 877在rails里面打开某个gem的类,补充一下等等,也 ... -
ruby的加载机制和rails_自动加载机制_对比
2014-09-02 16:51 1481prefer:http://urbanautomat ... -
Rails源码阅读(13)rails中的autoload和ruby的autoload
2014-07-30 17:13 1845Rails源码阅读(13)rails中的autoload和 ... -
Rails中命名路由的区别***_url与***_path
2014-07-29 16:37 1004Rails中命名路由的区别***_url与***_path ... -
ruby_gem安装_切换指定不同的源
2014-07-20 18:09 1083from:http://www.hiceon.com/to ... -
Ruby 的文件操作_不断总结
2014-07-11 11:55 1077一、用文件和目 ... -
Rails源码阅读(12)叫Rails的模块module_Rails常量使用
2014-07-02 09:35 973The module nams "Rail ... -
注册邮件中的链接无host
2014-05-19 14:47 575在注册邮件中用命名路由的xxx_url不起作用,导致注 ... -
每个命令都有bundle exec的麻烦
2014-04-18 17:33 1335问题: 每次都得搞这个东西bundle exec放在 ... -
关于favicon.ico的报错:RoutingError
2014-03-31 14:45 1840错误: ActionController::Routin ... -
rbenv_安装太慢_解决办法
2014-03-31 13:51 2073rvm做了很多“不为人知”的事情,而且做的太 ... -
配置sunspot tomcat结合sunspot_rails
2014-02-26 10:58 789这个sunspot的东西还是有不少缺点的。 ht ... -
RubyOrRails_使用技巧_收集
2013-11-09 14:39 993#link_to not working in sc ...
相关推荐
Windows上配置Ruby运行环境详解
ruby-debug命令详解~~~~~~~~~~~~~~~~~~~~~
而由于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+程序设计深入剖析与范例应用
ruby DBI ruby DBI ruby DBIruby DBI ruby DBI ruby DBIruby DBI ruby DBI ruby DBIruby DBI ruby DBI ruby DBIruby DBI ruby DBI ruby DBIruby DBI ruby DBI ruby DBIruby DBI ruby DBI ruby DBIruby DBI ruby DBI ...