• 哈哈~, 放心去学吧。我就是从 HTML+CSS 开始的。作为一个文科生,在大四才开始自学 PS/HTML/CSS, 出来后第一份工作就是 PS/HTML/CSS, 而后 ROR, 而后 RUBY, 再往下 LINUX, 数据库之类,而后回头来研究 JS. 就这样才一步步 FULL-STACK 的。

  • #15 楼 @moon2l ,3Q, 一直在找,都没有找到。谢谢啊谢谢 😄

  • #11 楼 @jasl 这个到更贵啊,$400+ 简直伤不起。

  • 为什么我们需要 Rack ? at 2014年09月14日

    再补上一份 Rack 的文档,详细,清晰,想深入研究的童鞋不要错过: http://www.doc88.com/p-209931998825.html

  • 为什么我们需要 Rack ? at 2014年09月13日

    #9 楼 @layerssss , 所以,最后说一点页面闪都不闪一下就打开了. 但是其实在后台, 无数的协议, 无数的进程, 这后面为你服务的家伙, 哪怕把名字列出来, 都够你看上二十小时. 那评论只是吐嘈,仅 web 相关,都不知道漏了个大环节多少。

  • atom 现在蛮好用的 at 2014年09月13日

    atom 确实很好用。如果它不是经常崩溃,我就用它取代 sublime. 至于现在嘛,就是用来写 markdown 了。 顺便分享下我使用 atom 写日记的配置:

    vim ~/.bash_profile

    #.bash_profile
    alias wrd="atom ~/diary/`date +%Y-%m-%d.md`"
    

    source ~/.bash_profile

    然后,在 terminal 中输入wrd 就可以直接以今天的日期新建或打开一个 markdown 文件。随意记上一些想法,做些笔记,有时还会写上 'xxx 是 SB`之类的文字 😄

    用它来写 markdown 的一个理由是,安装插件markdown-preview后按 CTRL+SHIFT+M组合键可以分栏预览 markdown.

  • 为什么我们需要 Rack ? at 2014年09月13日

    附上之前写的另一篇入门吐嘈文:

    这天你坐在电脑前,打开浏览器,并发送请求到 http://test.example.com/cons/1.

    你的浏览器根据实际情况生成了一个完整的Request. 根据全球邮政管理体系TCP/IP协议,这个请求被打包交给包裹公司,查询过一个叫DNS server的路人后,路人表示 text.example.com 指向 ip 是个邮编是 111.111.111.111 的大楼地址,于是这个请求信息的包裹被交给快递公司,经历无数次的中转 (路由/代理), 终于到了 111.111.111.111 大楼。因为你没有指定端口号,默认指向 80 端口。表示自己要找 80 号房的家伙。

    这个大楼简称 111 大楼,进楼时颇废周拆,一个叫防火墙的变态狂对包裹进行了全身检查,X 光照遍全身,以确认它安全健康,不含任何病毒,不带三聚氢铵等等危险成份。

    111 大楼总接待回头看了看业务表,确实有 80 号客房,而且对外开放,于是说,准! 而后客户到了 80 号房,敲了敲门,这个时候 80 号出来一个叫 nginx 的家伙,经过仔细的盘问作了来访登记 (log), 实际它对一些它自己能处理的东西,像化妆品 stylesheet, 图片之类的东西,它就直接帮你包好了。

    而后你的请求就进了 80 号房。80 号房按你写的邮编地址查询自身的来访规则,根据访问的前缀 test 表示有个家伙是专门处理你的请求的.(nginx virtual host) 它叫 passenger, 而后你的请求就交给了 passenger, passenger 转手扔给某个 app project 地址。

    这个时候,这个叫 hello 的 rails 或者说 rack app 已经等得快哭了。 因为 hello 经常遭遇恐怖袭击,所以你的请求需要经常严格的审核。这审核过程相当之严谨,主要由一个个职业叫middleware的家伙来完成。很有趣的是这帮家伙长着一样的脸:它们都响应一个叫 call 的方法,这个方法接受一个叫 env 的对象。无论中间做了什么,到最后他们必须返回一个盒子,里面装着万年好基友三剑客,它们的站位相当严格,永远是status code , head, body的纵队。

    它们有独特的品味:status code必须是整数在 100 到 599 之间。head是个穿着花裙子的hash, 里面放着各种奇怪的东西,除了几种常见的像Content-Type之类的东西,你时常会发现一些连大侦探 google 都查不出根脚的家伙。而且body必须响应一个叫each的方法。为什么 middleware 们的工作这样艰苦,限制这么多呢?因为有个叫Rack的家伙强制做了这样的要求,这家伙是法,是天,是规则,是道,贯穿着hello部门的始终。前面的家伙 (passenger/thin/mongrel/Webrick/Fast-cgi) 听它的,后面的家伙 (Rails/sinatra/Camping) 也听它的,如果 middleware 们不按它的要求来,就会被程序员们扯出肠子来打上传说中最最恶毒的猴子补丁以保证它们按 Rack 老大的规矩来办事. 这一个个的 middleware 排进一个叫 stack 的队伍中,严格按先进后出的原则努力工作。最后一个家伙大叫一声call(env)而后将自己丢给前一位的家伙,生成一个新的对象,而后再大叫一声call(env), 如此循环。

    这些苦逼的家伙们有的负责检查你的请求文件里有没有炸弹 (听说最近很流行邮寄炸弹),有的负责去掉非法的请求 (很明显你若是请求这栋楼的钥匙或是其他客户的信息是不可以),有的则分析你请求里的地址,而后决定交给哪个部门来处理。有的则会根据你请求的是get/post/put/delete/head/options等等来交给全不同的部门。

    总之,这个 111 大楼的 80 号房 passenger 分区的 hello 往下也分了无数个部门。简直是个俄罗斯套娃,一层包着一层无穷无尽。好在这个审请的过程不像有关部门的业务一样需要你亲自到场一个一个去打他们签字,包裹发出去就不用你干啥了。

    业务继续,middleware 们对你的请求逐词逐句地分析,某此必须请求未写的,给你补上默认的,保你格式规范。写错的若是小错误帮你改改,若是大错,就驳回了请重新请求。

    经过重重审核,你的请求文件已经变得他妈的都不认识他了。 终于,最后一道审核通过了。这个时候,80 号房 passenger 分区的 hello app 部门的各个负责回复的部门开始忙碌起来。它们一头扎进大楼的各地去给你找东西。比如说到楼下的楼下的楼下去一个叫数据库的地方去给你找来各条件的东西,带回来层层处理。这个过程甚至比请求进来时的层层安检处处审批都要复杂麻烦。比如说那个叫 ActiveRecord 的家伙在取回东西后要对它做各种包装,要去掉很多你不需要或者不方便看到的东西,封装成一件件货品。有时你表示你只需要一个罐头 (/show), 这种工作似乎相对容易,直接把罐头打包,而后丢给 view 车间,进入流水线,view 为它打上生产日期,过期时间,印上大幅的广告,而后给你就可以了。有时候你表示要一箱子,还要附带其客户的留言打分评价,那就是个相当繁琐的过程。

    详细点说:不同部门的处理是不一样的。比如说,有的部门会要求你交出身份证 (authtication), 有的会看看你是不是会员,还要查看你的权限 (Role based priority. member?/customer?/admin?), 有的会检查下你付过钱没有 (payed?).

    一般到了这里,就是称之为Logic的地方了。前面的都是外包的安全公司业务流程 (protocol, abstract logic), 到这里,就是到了 hello 的核心部门了。

    hello有五花八门部门。其中,最出名的有四个部门,分别是router, model, view, controller 简称万人迷 F4 组合。后三个家伙更出名,它们取各自名字的首字母,简称MVC超级无敌人气组合,它们名声在外,超出了 Rails 社区,超出发 Ruby 大陆,走向了更高的领域,无数的程序猿是它的粉丝,日日为之不眠,它们猩红的眼里一会儿是 M, 一会是 C, 一会是 V, 来来回回,永无止境。大体而言,router 根据请求找到合适的 C, C 负责接客,M 负责提供干货并交给 C, C 再交给 M 加工包装, C 再交给 V 加工包装,而后再由 C 发给客户。

    hello里有无数的临时工,临时工一般被称之为gem, 它们活跃在各种地方,做着最细致最精巧的活。但是也有不好的地方,它们拉帮结派,有时你只想雇佣其中一个家伙,结果却是得连他的亲朋好友加十代血亲的雇过来 (dependecies).有时候这些临时工会乱来,一个不好就会弄崩一条流水线。有时候是房子 (Rails/sinatra) 本身出了问题,也会造成它们的不适应并且造成很大的乱子,但是一般人都不会去怪房子本身,而会直接找它们的麻烦 (换掉或打上恶毒的猴子补丁). 好吧,这个时候它们是背黑锅的,有时候临时工协会等于背锅协会。

    在你与 111 大楼的 hello 公司进行一次交易后,为了保持以后合作愉快,它们在背后做了许多工作。比如说建议长期的联系,什么cookie啊,session啊,cache之类的干了无数的活。有的让你提交请求时不用每次都要查身份证,验指纹,核对瞳孔; 有的记录下你的喜好方便下次直接拿出你喜欢的酒; 有的则与你的浏览器热情交流以保证你下次访问可以更快更好; 还有的直接与你的浏览器搭上线,建立不断线通话,不再单纯地玩问答游戏,主动推送内容 (asyn), 如此种种不胜枚举。

    最后,东西终于到你手上了。但是实际上它们只是头文件字符串。这个时候,你亲切的管家 (浏览器) 开始工作了。它干的活比你想像中的还复杂,不过我已经无力吐嘈,看看这篇文章吧 [http://www.html5rocks.com/zh/tutorials/internals/howbrowserswork/]

    你表示,这次的请求相当愉快。这个网站的速度似乎还可以,由于你用的是 100M 光纤网络,一点页面闪都不闪一下就打开了。但是其实在后台,无数的协议,无数的进程,这后面为你服务的家伙,哪怕把名字列出来,都够你看上二十小时。

  • 此项目可部署:demo: http://learnmvc.zhuboliu.me/ 其中,products链接处不能访问,是因为这里需要引用数据库。

  • #4 楼 @limkurn , 我只看了 Rebuilding Rails 的免费部分,前几章而已。穷啊,40 美刀买不起。 参考了这本书的初始架构,其他的是我自己写的呢。

  • #2 楼 @huobazi , 还没有支持 API 返回呢。

  • AngularJS 初尝新作 at 2014年09月11日

    :plus1: 大爱ng啊。

  • Ryan Bates will be coming back at 2014年09月03日

    希望不是像 Why 先生一样消失了。那个通知是很久很久很久以前的了。

  • http://test.bianzhihui.com/t/3 呃,似乎是development mode啊~~

  • 我是来给大伙送航拍器的 at 2014年09月01日

    可惜手上的项目走不开,要不然就推荐我自己了。😄

    话说三个月前就收到 DJI 的猎头邮件了的。可惜啊可惜~~~

  • 我是来给大伙送航拍器的 at 2014年09月01日

    @_@, 还木有送出去吗~~~

  • 建议收录到 wiki 中。https://ruby-china.org/wiki/ruby-meta

  • 我是来给大伙送航拍器的 at 2014年08月25日

    #28 楼 @saberma , 哈哈,你去大疆了啊~~

  • 这里还有一个:https://github.com/Microsoft/TypeScript

    全原生 JS 支持,同时,加上自己的语法与限制。

    TypeScript is a language for application-scale JavaScript. TypeScript adds optional types, classes, and modules to JavaScript. TypeScript supports tools for large-scale JavaScript applications for any browser, for any host, on any OS. TypeScript compiles to readable, standards-based JavaScript.

    说来说去就是个如何写 JS 的问题。

  • :plus1:

  • 表示受不了了,直接 time machine 回到 MAC 10.9

  • @zjwzszh , 一个简单问题的多角度解决方案。重要的是在这个教程中所体现的思维方式。

  • Function is the first-class object. 意思是说,函数可以作为函数的参数传入,可以作为函数的值返回,也可以赋值给变量。如此等等,这些是 functional programming 的一大特性。如果说 ruby 里的元编程机制让 ruby 动态而且灵活,那 javascript 等函数式编程就是靠着以上特性而灵活,强大。理解 JS, 无非是函数/闭包/prototype. 这几点核心理解掌握了,JS 在手中就是利器了。

  • 通过 API POST photos 时的 BUG at 2014年08月08日

    #4 楼 @glorySpring , sorry for that. 我也没找到解决方案。上面贴出的解决方案都试过了,木有用。后来放弃了。rubychinaspa 已经被搁置很久了。

  • #1 楼 @Peter , 原本就是设计成 console 版的手册的。用排列组合的方式列出所有的可能的组合。但是一运行就是 800 余行的结果,实在不好用。于是就写了个网页版的。

  • #4 楼 @kewin , 没这么高端吧,那文件夹在/usr/local/Caller里,我都没去那里逛过,八九岁的小屁孩应该/可能玩不到那里去吧 x_x

  • #31 楼 @dalang , 如果你实在受不了那种写法,有一种写法倒是可以的:left, right = self.each_slice((self.length/2.0).ceil).to_a 测试代码如下:

    class  Array
      def zslice
        self.each_slice((self.length/2.0).ceil).to_a
      end  
    end  
    a = [1, 2, 3]
    b = [1, 2, 3, 4]
    a.zslice #=> [[1, 2], [3]]
    b.zslice #=> [[1, 2], [3, 4]]
    

    这种写法,一行搞定了问题,看起来是否舒服得多?(对强迫症病患者 😄 )

  • 呃,我是 MAC 小白。 查看 LOG, 如下:

  • #29 楼 @dalang , 3Q, 谢谢提醒。但是这样是不行的. 比如说,a = [1, 1, 2, 4], left = [1]. 那么,right = a - left, 得到的值是[2, 4], 很明显这样是不对的。

  • 既然是生产环境无 JS 效果,那就是 DEVELOPMENT MODE 是可以正确运行的。那就只有一个原因了。就是 precompile 时出现在 inject dependency 问题。也即是说,你应该以这种模式来写:

    myApp.controller(['$scope', 'X', 'Y', function($scope, X, Y){
       //your codes here.
    }]);
    

    具体看这里的例子http://plnkr.co/edit/DvBdX5?p=preview 里面有 4 种常见的定义 controller 的方法,但是只有一种会在 minify 或 precompile 时不出错。

  • 肿么会失败呢?直接升级就 OK 了啊。