稍后看看~~
Ruby Conf 2012 , 吕哥的传道,这一块儿就没有听明白的说....
哇~ 终于可以对 2.0 有一个较全面了解了。
非常感谢~
说起 ko1, 原来他就是写 YARI 那个?? 他的 github 页面刚刚发布了一个基于 ruby2.0 debug API 的 debugger2
不错~
难得整理,翻译过来就更好啦。
Cap 我还没开始用呢....
基本上看明白了你讲的语义,不过我觉得 #13 楼 @lgn21st 讲的更简单明了一些?
不过我也看出来一点:不是你们把简单问题复杂化,要怪只能怪 RSpec 做的太臃肿了。 这个观点不是我的,而是 MiniTest 的作者的。我只是转述一下。(貌似他是 Rspec 前作者之一)
下面是这两个方法在 MiniTest 的源码,通过这个源码就不难理解,为什么我的想法和你不太一样了。
##
# Essentially, define an accessor for +name+ with +block+.
#
# Why use let instead of def? I honestly don't know.
def self.let name, &block
define_method name do
@_memoized ||= {}
@_memoized.fetch(name) { |k| @_memoized[k] = instance_eval(&block) }
end
end
##
# Another lazy man's accessor generator. Made even more lazy by
# setting the name for you to +subject+.
def self.subject &block
let :subject, &block
end
MiniTest 的约定很简单:
主题
.#13 楼 @lgn21st 明白了默认 subject 的含义... (不过,那个例子中应该是 belongs_to ? )
另外,从源码中来看,有关 lazy-evaluated, let 和 subject 没有什么区别的。他们都是 lazy 的. 或者说:他们都是通过 block 方式实现了 lazy_evaluated. 代码中体现出来的只是,对象是通过一个上下文中的全局 Hash 被 Cached, 当复用时,无需反复创建对象。
我觉得 RSpec 大家都用的原因是:UnitTest 太慢了... 不过,现在的 MiniTest 已经比 RSpec 快很多了,现在已经 Ruby 2.0 & Rails 4 时代了,给个建议,大家是否可以考虑了解下 MiniTest ??
因为根本是两个概念呀。
Ruby 中至少到现在为止,不存在所谓的 包管理 ?? 你要是直接 hack 了一个核心类,则每一个应用都会受到影响,这就是常说的 Ruby 不适合大规模开发
所诟病的东西,refinement 就是在试图改善这个印象,将可影响的范围降到一个局部。不过 Ruby 2.0 p0 里面,这个特性还只是一个玩具...
module FooBar
refine String do
def hello
puts "Hello, world"
end
end
end
"str".hello # => No Method Error
using FooBar
"str".hello # => "Hello world"
探索精神赞一个~~
不过,是不是有点把简单问题复杂化了?是不是站在测试的角度来分析这两个东西,更清晰? 我觉得似乎我的答案还是好懂点?? 呵呵。
有几个问题:
# 使用 subject
describe CheckingAccount, "with $50" do
# 直接用的 Class Name,若此时没有显式定义 subject,那么默认的 subject 就是 CheckingAccount,可通过在代码中输出 subject 获知
subject { CheckingAccount.new(Money.new(50, :USD)) }
it { should have_a_balance_of(Money.new(50, :USD)) }
end
你注释是什么意思?如果没有定义 subject { ... }, 默认就是 CheckingAccount, 这默认怎么知道如何去初始化对象,难道会解析你那个 "with $50" ??
# 重构上面的例子
describe "Checking Account initialization" do
let(:starting_balance) { Money.new(50, :USD) }
subject(:account) { CheckingAccount.new(Money.new(50, :USD)) }
it "has $50 balance" do
expect(account).to have_a_balance_of(starting_balance)
end
it "has a balance attribute which equals the starting balance" do
expect(account.balance).to eq(starting_balance)
end
end
我就最后这个看得最清晰了,不过,我没看出来 这个里面 let 和 subject 有啥区别? 这种情况为什么不用两个 let ?
Ruby 2 实现了一个新的语法叫做 using, 的确是你想要的功能,不过貌似有较大的 bug, 在 Ruby 2.0 p0 中,只是作为一个实验性的尝试。
include A 混入的是 A 里面定义的实例方法。你搞错了 include 的含义。
@bhuztez 大神的话,总是很飘逸,让我等的思绪完全追不上...
我觉得那个姐姐有严重的强迫症...
嗯嗯,就像以前的我一样。
只给一句话箴言:(不是我原创的)
学 Ruby 没有捷径!
好吧,我先说有关提问的两点:
最后我还是回答好了,我不是大牛,我适合回答这样的问题。
let 以及 subject 是类似于 Minitest 中的 before 的简写形式
subject { ... } 定义了一个叫做 subject 的方法,它返回了代码块内定义的那个对象. let(:a) { ... } 定义了一个叫做 a 的方法,他也是返回了代码块内定义的那个对象。
我把楼主的意思详细描述一下:
首先要写测试 ... 当然你必须知道如何写 正确的测试
. <单元测试>
如果测试可以正确的写出来,你往往需要做很多事,例如重构,重构再重构。
你测试终于写出来了,也通过了,爽!这证明我的代码现在执行是正确的。
而且这些测试可以作为 回归测试
, 即:它可以保证将来修改代码之后的代码也总是正确的,我不会在同一个地方,再次摔跤...
最后,你突然发现,经过这个过程之后...
你的代码变的 优雅
, 易懂
了...
你说的是 ARM 架构的 Surface RT, 那是个纯平板. 我说的是 Inter 架构的 Surface Pro, 这是个平板化的手提电脑。
后者可以关闭 Secure Boot 的。前者不行。
.... Win8 太大了,如果我用这个机器,我从没想过还保留 Win8.