- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章Ruby 魔法 学习笔记之一由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
1、向对象显示的发送消息 我们可以向对象直接发送消息: Ruby代码 。
复制代码 代码如下
class HelloWorld def say(name) print "Hello, ", name end end hw = HelloWorld.new hw.send(:say,"world") 。
我们通常使用hw.say("world"),但send可以对private的方法起作用。 不光如此send可以使程序更加动态,下面我们看看一个例子: 我们定义了一个类Person,我们希望一个包含Person对象的数组能够按 照Person的任意成员数据来排序: Ruby代码 。
复制代码 代码如下
class Person attr_reader :name,:age,:height def initialize(name,age,height) @name,@age,@height = name,age,height end def inspect "#@name #@age #@height" end end 。
在ruby中任何一个类都可以随时打开的,这样可以写出像2.days_ago这样优美 的code,我们打开Array,并定义一个sort_by方法: Ruby代码 class Array def sort_by(sysm) self.sort{|x,y| x.send(sym) <=> y.send(sym)} end end 我们看看运行结果: Ruby代码 people = [] people << Person.new("Hansel",35,69) people << Person.new("Gretel",32,64) people << Person.new("Ted",36,68) people << Person.new("Alice", 33, 63) p1 = people.sort_by(:name) p2 = people.sort_by(:age) p3 = people.sort_by(:height) p p1 # [Alice 33 63, Gretel 32 64, Hansel 35 69, Ted 36 68] p p2 # [Gretel 32 64, Alice 33 63, Hansel 35 69, Ted 36 68] p p3 # [Alice 33 63, Gretel 32 64, Ted 36 68, Hansel 35 69] 这个结果是如何得到的呢? 其实除了send外还有一个地方应该注意attr_reader,attr_reader相当于定义了name, age,heigh三个方法,而Array里的sort方法只需要提供一个比较方法: x.send(sym) <=> y.send(sym) 通过send得到person的属性值,然后在使用<=>比较 2、定制一个object << object ruby不仅可以打开一个类,而且可以打开一个对象,给这个对象添加或定制功能,而不影响 其他对象: Ruby代码 a = "hello" b = "goodbye" def b.upcase gsub(/(.)(.)/)($1.upcase + $2) end puts a.upcase #HELLO puts b.upcase #GoOdBye 我们发现b.upcase方法被定制成我们自己的了 如果想给一个对象添加或定制多个功能,我们不想多个def b.method1 def b.method2这么做 我们可以有更模块化的方式: Ruby代码 b = "goodbye" class << b def upcase # create single method gsub(/(.)(.)/) { $1.upcase + $2 } end def upcase! gsub!(/(.)(.)/) { $1.upcase + $2 } end end puts b.upcase # GoOdBye puts b # goodbye b.upcase! puts b # GoOdBye 这个class被叫做singleton class,因为这个class是针对b这个对象的。 和设计模式singleton object类似,只会发生一次的东东我们叫singleton. << self 给你定义的class添加行为 Ruby代码 class TheClass class << self def hello puts "hello!" end end end TheClass.hello #hello! <<self修改了你定义class的class,这是个很有用的技术,他可以定义class级别 的helper方法,然后在这个class的其他的定义中使用。下面一个列子定义了访问 函数,我们希望访问的时候把成员数据都转化成string,我们可以通过这个技术来 定义一个Class-Level的方法accessor_string: Ruby代码 class MyClass class << self def accessor_string(*names) names.each do |name| class_eval <<-EOF def #{name} @#{name}.to_s end EOF end end end def initialize @a = [ 1, 2, 3 ] @b = Time.now end accessor_string :a, :b end o = MyClass.new puts o.a # 123 puts o.b # Fri Nov 21 09:50:51 +0800 2008 通过extend module给你的对象添加行为,module里面的方法变成了对象里面的 实例方法: Ruby代码 module Quantifier def any? self.each { |x| return true if yield x } false end def all? self.each { |x| return false if not yield x } true end end list = [1, 2, 3, 4, 5] list.extend(Quantifier) flag1 = list.any? {|x| x > 5 } # false flag2 = list.any? {|x| x >= 5 } # true flag3 = list.all? {|x| x <= 10 } # true flag4 = list.all? {|x| x % 2 == 0 } # false 3、创建一个可参数化的类: 如果我们要创建很多类,这些类只有类成员的初始值不同,我们很容易想起: Ruby代码 class IntelligentLife # Wrong way to do this! @@home_planet = nil def IntelligentLife.home_planet @@home_planet end def IntelligentLife.home_planet=(x) @@home_planet = x end #... end class Terran < IntelligentLife @@home_planet = "Earth" #... end class Martian < IntelligentLife @@home_planet = "Mars" #... end 这种方式是错误的,实际上Ruby中的类成员不仅在这个类中被所有对象共享, 实际上会被整个继承体系共享,所以我们调用Terran.home_planet,会输出 “Mars”,而我们期望的是Earth 一个可行的方法: 我们可以通过class_eval在运行时延迟求值来达到目标: Ruby代码 class IntelligentLife def IntelligentLife.home_planet class_eval("@@home_planet") end def IntelligentLife.home_planet=(x) class_eval("@@home_planet = #{x}") end #... end class Terran < IntelligentLife @@home_planet = "Earth" #... end class Martian < IntelligentLife @@home_planet = "Mars" #... end puts Terran.home_planet # Earth puts Martian.home_planet # Mars 最好的方法: 我们不使用类变量,而是使用类实例变量: Ruby代码 class IntelligentLife class << self attr_accessor :home_planet end #... end class Terran < IntelligentLife self.home_planet = "Earth" #... end class Martian < IntelligentLife self.home_planet = "Mars" #... end puts Terran.home_planet # Earth puts Martian.home_planet # Mars 4、Ruby中的Continuations: Continuations恐怕是Ruby中最难理解的概念了,它可以处理非局部的跳转, 它保存了返回地址和执行的环境,和c中的setjmp和longjump类似,但它保存 了更多的信息: axgle举的曹操的例子很形象,我们拿过来看看: 来自[http://www.javaeye.com/topic/44271] 曹操(caocao)被誉为“古代轻功最好的人 ”,是因为“说曹操,曹操到”这句名言。 在ruby中,曹操的这种轻功被称为callcc. Ruby代码 callcc{|caocao| for say in ["曹操","诸葛亮","周瑜"] caocao.call if say=="曹操" puts say #不会输出,因为曹操已经飞出去了 end }#“曹操”飞到这里来了(跳出了callcc的block,紧跟在这个block后面,继续执行下面的ruby代码) puts "到" callcc里的caocao是个"延续"(Continuation)对象.这个对象只有名叫“call"的这样一个方法。 当执行了caocao.call后,caocao就会飞到callcc的块(block)后面,让ruby继续执行其下面的代码。 我上面给出的是一个从块里头”飞“到块外面的例子;下面是Programming Ruby给出的从代码后面”飞“到代码前面的例子: Ruby代码 arr = [ "Freddie", "Herbie", "Ron", "Max", "Ringo" ] callcc{|$cc|}#下面的$cc.call如果被执行,就会飞回到这里(callcc的块之后)。 puts(message = arr.shift) $cc.call unless message =~ /Max/ 例子大多来自<<The ruby way>> 。
最后此篇关于Ruby 魔法 学习笔记之一的文章就讲到这里了,如果你想了解更多关于Ruby 魔法 学习笔记之一的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
以下是一个非常简单的ruby服务器。 require 'socket' local_socket = Socket.new(:INET, :STREAM) local_addr = Socket.
我正在使用 OS X(使用 bash),并且是 unix 的新手。我想知道是否可以修改一些文件以便运行 ruby 程序,我不需要“ruby file.rb”,而是可以运行“ruby.rb”。 有理
我在用 Ruby 替换字符串时遇到一些问题。 我的原文:人之所为不如兽之所为。 我想替换为:==What== human does is not like ==what== animal does.
我想在一个循环中从 Ruby 脚本做这样的事情: 写一个文件a.rb(每次迭代都会改变) 执行系统(ruby 'a.rb') a.rb 将带有结果的字符串写入文件“results” a.rb 完成并且
我的问题是尝试创建一个本地服务器,以便我可以理解由我的新团队开发的应用程序。我的问题是我使用的是 Ruby 2.3.3,而 Gemfile 需要 2.3.1。我无法编辑 Gemfile,因为我被告知很
我有一个使用 GLI 框架用 Ruby 编写的命令行实用程序。我想在我的主目录中配置我的命令行实用程序,使用 Ruby 本身作为 DSL 来处理它(类似于 Gemfile 或 Rakefile)。 我
我的 Rails 应用 Controller 中有这段代码: def delete object = model.datamapper_class.first(:sourced_id =>
我正在寻找的解析器应该: 对 Ruby 解析友好, 规则设计优雅, 产生用户友好的解析错误, 用户文档的数量应该比计算器示例多, UPD:允许在编写语法时省略可选的空格。 快速解析不是一个重要的特性。
我刚开始使用 Ruby,听说有一种“Ruby 方式”编码。除了 Ruby on Rails 之外,还有哪些项目适合学习并被认可且设计良好? 最佳答案 Prawn被明确地创建为不仅是一个该死的好 PDF
我知道之前有人问过类似的问题,但是我该如何构建一个无需在前面输入“ruby”就可以在终端中运行的 Ruby 文件呢? 这里的最终目标是创建一个命令行工具包类型的东西。现在,为了执行我希望用户能够执行的
例如哈希a是{:name=>'mike',:age=>27,:gender=>'male'}哈希 b 是 {:name=>'mike'} 我想知道是否有更好的方法来判断 b 哈希是否在 a 哈希内,而
我是一名决定学习 Ruby 和 Ruby on Rails 的 ASP.NET MVC 开发人员。我已经有所了解并在 RoR 上创建了一个网站。在 ASP.NET MVC 上开发,我一直使用三层架构:
最近我看到 Gary Bernhardt 展示了他用来在 vim 中执行 Ruby 代码的 vim 快捷方式。捷径是 :map ,t :w\|:!ruby %. 似乎这个方法总是执行系统 Rub
在为 this question about Blue Ruby 选择的答案中,查克说: All of the current Ruby implementations are compiled to
我有一个 Ruby 数组 > list = Request.find_all_by_artist("Metallica").map(&:song) => ["Nothing else Matters"
我在四舍五入时遇到问题。我有一个 float ,我想将其四舍五入到小数点后的百分之一。但是,我只能使用 .round ,它基本上将它变成一个 int,意思是 2.34.round # => 2. 有没
我使用 ruby on rails 编写了一个小型 Web 应用程序,它的主要目的是上传、存储和显示来自 xml(文件最多几 MB)文件的结果。运行大约 2 个月后,我注意到 mongrel 进程
我们如何用 Ruby 转换像这样的字符串: 𝑙𝑎𝑡𝑜𝑟𝑟𝑒 收件人: Latorre 最佳答案 s = "𝑙𝑎𝑡𝑜𝑟𝑟𝑒" => "𝑙𝑎𝑡𝑜𝑟𝑟𝑒" s.u
通过 ruby monk 时,他们偶尔会从左侧字段中抛出一段语法不熟悉的代码: def compute(xyz) return nil unless xyz xyz.map {|a,
不确定我做错了什么,但我似乎弄错了。 问题是,给你一串空格分隔的数字,你必须返回最大和最小的数字。 注意:所有数字都是有效的 Int32,不需要验证它们。输入字符串中始终至少有一个数字。输出字符串必须
我是一名优秀的程序员,十分优秀!