• geetest ruby sdk at 2014年05月15日
    /*
    破解 http://geetest.com/tryit/
    打开浏览器在console里面运行如下代码
    加载jquery模拟drag脚本,考虑到滑块大小,第一次直接拖动到50px,后续每秒钟拖动8px
    从人工拖动的结果可以看出,该验证码方式位置误差在+/- 5px左右,所以50px+8px这样简单粗暴的2行代码就可以有30%的成功率
    破解失败情况是在滑块缺口位置偏右了,导致尝试太多
    加上图像识别滑块缺口位置,就可以轻松100%地破解
    */
    
    function d(first) {
    $('.gt_slider_knob').simulate('drag', { dx: first ? 50 : 8 });
    setTimeout(function(){d(false);}, 1000);
    }
    
    jQuery.getScript("https://raw.githubusercontent.com/jquery/jquery-ui/master/tests/jquery.simulate.js", function() {
    d(true);
    });
    
  • #1 楼 @rociiu 70 后压力更大

  • 帕劳 这个目的地好赞!

  • 排列组合题 at 2014年05月04日
    b.count{|e| (c - e).empty?}
    
  • #17 楼 @bhuztez 嗯,常用 Rails 的 ruby 程序员一定不觉得这是 ruby 代码 ...

  • #7 楼 @bhuztez 没有体现出 ruby 的函数式编程,打回重写,哈哈哈

  • 写了一个让人觉得高(看)大(不)上(懂)Ruby 函数式:

    n = [3,5,7]
    w = %w(Fizz Buzz Whizz)
    
    l = -> a,fn {[fn.(a)] + a.combination(2).map{|_| fn.(_)} + a}
    ns, ws = l.(n, -> _ {_.inject(:lcm)}), l.(w, -> _ {_.join})
    
    1.upto(100).map{|i| i.to_s =~ /#{n[0]}/ ? w[0] : (f = ns.find_index{|l| i % l == 0}) ? ws[f] : i }
    
  • haml slim 之流真的好吗? at 2014年04月26日

    #46 楼 @darkbaby123 不需要选定一堆代码,只要在你想要缩进段的开始行,按 ctrl+shift+[ 就折叠了,然后按 tab 缩进,2 个快捷键搞掉,连鼠标都不需要用。

  • haml slim 之流真的好吗? at 2014年04月25日

    #24 楼 @darkbaby123 关于 1,有编辑器支持毫无压力,比如 sublime,可以折叠整块代码段成一行,对该行缩减就可以了,默认快捷键 ctrl+shift+[

    关于 2,没这个体会,举个具体例子吧

  • #26 楼 @huacnlee 我记得文档上有说不能小于 150K/S 还是 200K/S 来的...

  • #16 楼 @layerssss 原来如此...

    btw, 这个比赛好像参加人不多呢,在想要不要去试试手气,混个奖什么的,可是看了一下他的选题,没什么好玩的 idea

  • #11 楼 @huacnlee 创建空间的时候选择 CDN 类型,后续就可以配置源的域名和 IP 了

  • 又拍现在不是已经支持镜像空间了吗?直接用本机做 asset 源,又拍做 CDN 就好了,不需要额外上传。

  • haskell 和 ruby 都是函数式,只不过 haskell 有内置 fmap,just,nothing 等,而 ruby 没有,ruby 实现类似的也很简单:

    fmap = ->(f, x) do
      x.nil? ? nil : f.(x)
    end
    
    getPostTitle = ->(post) { post.title }
    findPost = ->(id)  {Post.where(:id => id).first}
    
    fmap.(getPostTitle, findPost.(1)) # return post 1 title
    fmap.(getPostTitle, findPost.(0)) # return nil
    

    只不过对于这种需求,ruby 一般不用函数式编程,而是用 #2 楼 @jasl 提到的 rails 扩展的 try 这种声明式编程

  • 这个代码有问题: DateTime.parse(Time.now.to_s) - DateTime.parse(current_user.created_at.to_s) < 7

    改成 (Time.now - current_user.created_at) < 7.days

  • 常见最简单的分库策略,按用户 id 来做 mod,比如有 5 台数据库服务器,那么用户 id % 5,先计算出该用户落在那台服务器。数据库里的表结构和#5 楼 @hooopo 一样,不过为了反向查找被关注,需要多加一个被关注的表,和关注表是冗余,在关注的时候同时在 2 个表里面插入。

    需求 1,2 在单台数据库用单句 sql 查询即可。需求 3,需要 2 次 sql 查询,再在内存中计算。

    复杂一些的分库策略,常用注册时间或者用户 ID 区间定义,来保证新加的服务器能够快速分配到新用户。

  • Ruby 2.1 现在稳定吗? at 2014年03月31日

    非常稳定

  • 一个还算好玩的题目 at 2014年03月22日

    2 ** 10 = 1024 > 1000

    binary mask 看死了哪些鸡就知道了

  • 支持 meta programming 的语言都很容易做到这个事情,python 是做了个语法糖方便调用,而 ruby 没有内置的语法糖,拿对应的例子来说,先来看给函数打日志,对应的 ruby 版本:

    module Decorator
      def logger(fn)
        m = Module.new do
          define_method(fn) do |*args|
            result = super(*args)
            puts "function = #{fn}"
            puts "  arguments = #{args.join(',')}"
            puts "  result = #{result}"
            result
          end
        end
        prepend m
      end
    end
    
    class Calculator
      extend Decorator
    
      logger(:multipy)
      def multipy(x, y)
        x * y
      end
    
      logger(:sum_num)
      def sum_num(n)
        1.upto(n).inject(:+)
      end
    end
    
    Calculator.new.multipy(2,10)
    Calculator.new.sum_num(100)
    

    创建一个 module,在里面重新定义这个函数,然后 prepend 这个 module,用这个 module 也很简单,只要 extend 一下,和 python 的语法糖相比,就是要多打入函数名。

    然后看对应的斐波拉契 memo 例子:

    module Decorator
      def memo(fn)
        m = Module.new do
          cache = {}
          define_method(fn) do |*args|
            cache[args] ||= super(*args)
          end
        end
        prepend m
      end
    end
    
    class Fibonacci
      extend Decorator
    
      memo(:fib)
      def fib(n)
        n < 2 ? n : fib(n - 1) + fib(n - 2)
      end
    end
    
    Fibonacci.new.fib(100)
    

    可以看到,和第一个例子的流程是一样的:

    1. 创建匿名 module
    2. 重新定义同名函数
    3. 做一些 decorator 的代码
    4. prepend 这个 module

    不同的 decorator 只是在第 3 步要做不同的事情,只要封装一下上面的逻辑,就可以做一个类似 python 的 wraps 类出来。

  • 如果你的数据量不多,可以用位操作来处理:

    zh => 1
    en => 2
    jp => 4
    
    Post.create(:locales => 1 + 2) # zh, en
    Post.create(:locales => 1 + 4) # zh, jp
    Post.create(:locales => 2 + 4) # en, jp
    
    Pos.where("locales & 1 > 0") #查询locale 为 zh
    Pos.where("locales & 5 > 0") #查询locale 包含 zh或者jp
    

    缺点是无法利用 locales 上的索引,数据量大的话,还是另外建立关联一个表来查询更加方便。

    =======编辑分割线======= #5 楼 @_kaichen 已经提供一个 gem 来封装了我说的查询和创建,赞。

  • #6 楼 @wcp1231 嗯,Enumerable 有很多方便的内置方法

  • A.each_cons(2).map{|e| e[1] - e[0]}
    
  • #16 楼 @swordray 查看了一下第 3 方流量分析,你们的网页访问比我们还低,预计在每天 3K~4KUV,30K~50K PV,这样的流量确实 2 台服务器就够了...

  • #33 楼 @willmouse 穷人版 before filter

    def before_filter(filter, methods)
      methods.each do |m|
        alias_method "__before__#{m}", m
        define_method(m) {send filter; send "__before__#{m}";}  
      end
    end  
    
    class Foo
      def show
        p "show"
      end
    
      def edit
        p "edit"
      end
    
      before_filter :bar, [:show, :edit]
    
      def bar
        p "bar"
      end
    end  
    
  • Campo 3 发布 at 2014年03月07日

    @Rei 赞 另外,有个疑惑,是出于什么考虑自己写了一个用户模块,而不是用 devise?用 devise 的话,其他应用集成或者做扩展会省力很多,而且代码量会少很多。

  • #12 楼 @leomayleomay restful api 设计从来没有要求 resources 必须用复数形式来表达

  • 我觉得 rails 使用复数形式来做 table name 和 restful api,带来太多的麻烦,在实际用途中,共用一个词的单复数形式来做 route 的情况大家都会改个名字,避免误解,比如同时用 users(用户集合)和 user(当前用户) resources :users resource :user

    通常第 2 个都会改成 resource :profile

    只用单数可以少去大量的反射(外键,表名,controller 等等)