我对 doctest 的期待是,有例子的文档,并且这些例子是可以跑的通的。 写注释的时候,写例子方便理解和调试。
doctest 里,如果测试特别多的时候,会对阅读有影响。测试变复杂的时候,doctest 也会显得比较吃力。
鼓励在注释里写例子,但能作为测试,只是 bonus。
s.split(" ").join("-").capitalize
没理解为啥要模仿 ->
这种操作符。
DateTime
?
另外这个判断,单独写比较好。
比如 longer_than_xx? = (Datetime.parse("Dec click_this_time") - Datetime.parse("Dec click_last_time"))/3600 > 24
如果是用 form 的话,可以用这种 https://stackoverflow.com/a/23497023/2477886
sublime 或者 ide,因为简单, 想玩的看起来牛逼一点,emacs 或者 vim
我的同事也问过我为啥一定要用 form_for。我说我们是用 Rails 的,不是写 php 的,既然用了,就试着写出 rails stype 的东西吧。
ActionView::Helpers
里面这么写的
Form helpers are designed to make working with resources much easier compared to using vanilla HTML.
rails 在做数据库的操作的时候,有很多约定。比如 User.find(1).update(name: "bar")
就直接做了更新。那生成的代码,就要符合这样的约定。
多数时候,更新和创建我们会使用类似的 form,只是 url 和 request method 不同。我们可以判断,要更新的对象是不是 new_record?
来生成对应的代码。
这个时候,你会发现手写,就要处理一些逻辑上的问题,那么引入 helper 就是一个不错的选择。
其实这个时候,还不算有趣。如果 user 有很多 (has_many) books 呢?如果想要在一个表单做 books 的操作呢?
可以这么搞,Book.new.book_attributes = [:name => "Ruby"]
(之前要声明 accepts_nested_attributes_for :book
) 。
这个时候,如果我们想用这个约定,就要构建对应的 form,要根据 nested 的关系构建对对应的 input 的字段。books 还是有序的。等等一系列的操作,但 form_helper 都帮我们搞定了。
到现在,其实已经没有不用 form helper 的理由了。但 rails 没有止步于此。rails 用继承的方式,避免了代码上的重复 -- FormBuilder
。
我们看下面的代码
<%= form_for(@company) do |f| %>
<%= f.text_field :name %>
<%= f.submit %>
<% end %>
多数的 input 前是要放 label,有一天,我们不想在写这样重复的代码,怎么办? FormBuilder
!
可以这样搞
class LabellingFormBuilder < ActionView::Helpers::FormBuilder
(field_helpers - [:label, :check_box, :radio_button, :fields_for, :hidden_field, :file_field]).each do |selector|
class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
def #{selector}(method, options = {}) # def text_field(method, options = {})
@template.send("label", @object_name, method) +
@template.send( #{selector.inspect}, @object_name, method, objectify_options(options))
end
RUBY_EVAL
end
end
<%= form_for(@company, builder: LabellingFormBuilder) do |f| %>
<%= f.text_field :name %>
<%= f.submit %>
<% end %>
具体可以看看这篇文章 https://segmentfault.com/a/1190000004425543 (只有一,没有二、三。。。)
很多 ruby 程序员,说 simple_form 不好用。
但 simple_form 是大大的简化了代码。怎么搞呢,直接 custom 一个 form_builder 来,然后,大家套用这个 builder 就可以了。
custom 一个 form_builder 难不难呢?我们优秀的前端小伙 zack,第一次玩,就 custom 出来了一个。
先说,这是一个非常好的问题。
除了这些便利无法享受到以外。项目中的每一个人,每一个 form,都要重头写 form!都要了解 rails 的细节,都要了解 HTML form 的细节(笔记 array 在 rails 里生成的参数是什么样的?)。
代码变得不可 review -> 错误不好发现 -> 隐藏的 bug。
Rails 复杂,就是因为 Rails 提供了很多这样的便利。
有的时候,难免会想,这些到底值不值得?
accepts_nested_attributes_for
我第一次用,也是一脸懵逼。但我花了一天左右的时候,就搞差不多了,顺带还知道 Rails 的很多细节,比如 create、update 几个方法的关系。影响了我后今后的编码生涯(虽然听着很夸张,但却是如此)。以后 form 可以用的很爽。
搞了这么多,做起来难不难?不难,就像 simple_from,我们前端的小哥,半天就定制好了!Rails 难的时候,可能是你用它的姿势不对。
框架,不但能提供了好用的方法,能解决常见的问题。
还封装了细节,让我们不那么懂的时候,可以写出东西来。
提供了解决问题的姿势,大家可以用一样分流程解决类似的问题。
用 Rails,不能写完业务就万事大吉,还要读文档,了解 Rails 的机制。
八成是,现在不给钱,要钱?以后给。。。
没人会否认 Lisp/Clojure 的价值。语言有自己的特点,也有自己的适用范围。
有很多人从 Ruby 转向 clojure,也有很多人在用 ruby 做函数式的尝试。
Ruby / Rails 本身都在函数式编程上学习了很多。比如 rails 的 ActiveRecord::Relation
User.wher(xx: xx).find(xx) 。每一个方法都返回一个 ActiveRecord::Relation 的实例,而且是 lazy evaluation 的。
Clojure 也在做解决状态的尝试,比如 https://github.com/stuartsierra/component 。
面向对象,会带来复杂度,但也能解决问题,比如被很多 rails 程序员诟病的 https://github.com/josevalim/inherited_resources ,也可以极大程度上提高生产力。开发效率和能力成正比。这种东西所带来的好处就是,大多数情况下,隐藏了细节,团队开发就变成了有经验的 + 经验少的这种组合。而不是所有人都要有经验。
有些问题,需要通过 提供抽象、提供解决方案来解决。 比如创建数据,需要用到 factory,需要实现的就是 factory_girl 的那些方法,无论是 ruby 还是 clojure。
高手潜水呀
ruby-china 也有人潜水。但国内有很多牛人都不潜水,有管理论坛的的,有回答新手问题的、有分享撕逼的。至少看起来,是团结、热闹的。
同样的帖子,http://clojure-china.org/t/clojure-sdk/691 ruby-china 的热度更高啊!
搜索搜到这个帖子,没啥事,就试着写了下,跑通那几个用例,一共用了不到 30 分钟。
感觉挺好写的。这个算法我知道怎么回事。翻译成代码就 ok 了,ruby 又这么好写。二分法的递归也是属于比较容易的递归。写个骨架,然后再加最简单的测试用例(下面的前 4 个),之后对着用例开始微调,无外乎就是加减 1 的问题,试几次就 ok 了。再之后,就看看给的测试用例有没用问题。
递归转遍历,只要理解递归的原理,把递归维护的状态
,手动维护下,就 ok 了。反正测试用例有了,测试一直跑的,开始微调。
倒是觉得测试用例挺重要的。要是让我直接用面试官给的用例,我估计就要懵逼了。
递归是基本功。可以很好的锻炼抽象和分解问题的能力。递归学东西,一大片算法可以随便撸了。
递归可以这么考,先递归实现,之后用尾递归实现,再之后用遍历实现。再问问为啥尾递归可以被优化之类的。哈哈哈哈,我承认我挺无聊的。。。
代码如下,算法相关的,就没注意命名之类的问题。
## recursive version
def binary_search_helper(arr, ele, start, end_)
return false if start > end_
middle = (start + end_) / 2
middle_ele = arr[middle]
if ele > middle_ele
binary_search_helper(arr, ele, middle + 1, end_)
elsif ele < middle_ele
binary_search_helper(arr, ele, start, middle - 1)
else
middle
end
end
def binary_search(arr, ele)
end_ = arr.length
binary_search_helper(arr, ele, 0, end_ - 1)
end
def expect(r, expected)
unless r == expected
puts expected
else
puts "Success"
end
end
## iterative version
def binary_search_helper(arr, ele, left, right)
return false if left > right
while left <= right
middle = (left + right) / 2
middle_ele = arr[middle]
if ele > middle_ele
left, right = middle + 1, right
elsif ele < middle_ele
left, right = left, middle - 1
else
return middle
end
end
false
end
def binary_search(arr, ele)
length = arr.length
binary_search_helper(arr, ele, 0, length - 1)
end
expect binary_search([0], 0), 0
expect binary_search([0], 1), false
expect binary_search([0], -1), false
expect binary_search([], 0), false
expect binary_search((1..15).to_a, 8), 7
expect binary_search((1..15).to_a, 1), 0
expect binary_search((1..15).to_a, 14), 13
expect binary_search([2,3,8,15], 8), 2
破解密文是为了达到某种目的。
通过事实验证。 比如破解登陆密码,那么,拿这个密码登陆下就知道对不对了。再比如二战时候,破解的密文,就包含要攻打某某地的信息,只要真的攻打这个地方了,就能证明破解正确。
明文实际上就是看起来的“乱码”怎么办 接着破解。本来就是乱码的话,只能说,人家在逗你玩。。。
一个加密算法的安全性,是建立同时知道明文和密文的前提下,是否能得到秘钥。
可以呼吁,可以倡导,但不要给别人下定义。让人反感。
view 里面调用了 edit 那个路由,我猜是没声明找回密码的路由,试试这个 https://stackoverflow.com/a/7403353/2477886 。
如果还是不行,试试重启下 sidekiq。
[ 招聘]
多了一个空格, [招聘]
暴露我年龄
办活动不容易
CEO 人很靠谱
加油加油!望楼主坚持下去!
我觉得深究这些东西,还有一个原因,就是好奇。就是想搞懂到底是怎么回事。
从认知过程上来说,人理解事物需要时间。一个技能,连着学 7 小时的效果远不及每天学 1 小时,学 7 天效果来的好。
但效率是可以提高的。但对老师,学生、习题、教材要求都十分高。berkeley 有在教 SICP(简化版),学时是 4 个月。知识量非常惊人。
比如,定义变量、函数都能提高优先级,维护性更好。比如递归。比如分解问题。都是通过课程学习到的。
有些是观察别人(同事多一些)是怎么处理的。有些是别人告诉我的,比如 CTO 跟我 carrierwave
把一个开发级别的任务,变成配置级别的任务。一下就明白了一个 gem 的意义。
有些是自己坑自己,一边骂自己傻逼,一边默默填坑。
比如我在学递归的时候,怎么都不会。是按照老师、教材(sicp)的思路,才开始理解递归。 之后写了几个月的 clojure(遍地递归),撸了门算法课(撸的第二门了。。。),每一次都有更进一步的理解。
我对 ROR 理解是,几个人,能力最强的那个,搭架子,别人搬砖。
在比如 simple_form,有一个人懂就可以,剩下的人,有问题,就找那个人解决就好。
新人开始的时候,能照葫芦画瓢就好。知道 rails 的概念,看完 guides,看完 ruby 元编程。之后了还要知道 rails 的实现思路。HTTP,数据库等知识。
最后,学习这东西,要想学好,需要付出很大的努力,包括时间、别人的指点、正确的方法。
@sec 如果只是想学东西的话,可以不要那个证书,就是免费的。
楼主的分析挺正确! 这门课程是伯克利本科高年级的课程,建议学过 cs61a 或者 cs61b 的人学,要求是,有较好的编程基础。 这门课程讲到了软件工程的方法面面,全面但深刻,关键点都讲到了,剩下的可以在实践中慢慢体会。
顺便说一句,作为写过几年代码的人,我始终认为,写测试比写代码难。。。
语法好啊,很适合那群搞数学的。 还有数据随随便便就能读进来。 当然还有轮子多。
poltergeist
问题很邪乎,经常是有的机器上有问题,有的没有。
我本地跑了下,似乎是用到了 CSS Animations,可以先试试直接禁用掉(很多都这么干),具体可以参考这个链接
还可以点击事件换成find('#xxx').trigger('click')
,这个是不管是否有遮挡,都能 click。
我直接 revert 8f5df2358e7ee9c9a65d0412e0299e4f14659564 这个 commit,集成测试是可以跑过的。配置应该没问题。我猜可能是 phantomjs 版本的问题,我本地的是
phantomjs --version
2.1.1
另外 selenium 和 poltergeist 方法有一些的不同,同时使用(我们一个用在本地调试,一个用于 CI),略蛋疼,有想解决办法,但一直也没时间去搞。
同时建议使用screen_size: [1400, 1400]
,因为屏幕太小的话,会有因为点不到东西(元素不在显示器内)而报错的时候。
只是对自己的看法罢了。不会把这种看法加到别人身上,能解决问题,就是好样的。我对我自己的希望就是基础功再扎实一点。记忆本来就是学习的一部分,遗忘也是。
要求本来就是多样的。 很多时候要求不一样,比如 form 可以手写,可以用 form_for。有的时候我还会建议去了解 form_for 如何构建参数的,参数拿到了如何做赋值的。
需求总是多种多样的,总有彼此合适的。
我毕业的时候数学不会,算法不不会,数据库不会。但都慢慢补回来了。倒不是觉得这些在工作中能用到,而是觉得作为一个程序员,这些不会,说不过去。 再一个就是给自己一个可能。真的有一天要用到这些呢,比如实现个算法,比如玩玩机器学习?数学、算法这些都是没办法在短时间学会的。