• #5楼 @darkbaby123 "You Don't Know JS" +1 还有还有,Ruby和JS的内部原理都差不多,都源自smalltalk+scheme_lisp, 强烈推荐

  • 和为定值的随机数 at 2015年01月10日

    如果是求 >=4 的10个随机数,就比较简单:

    def samples_for_sum(sum, k) # generate k rand values greater than 1, whose sum is 'sum'
      seq = [0] + (1...sum).to_a.sample(k-1).sort + [sum]
      seq.each_cons(2).map{|pre, cur| cur-pre}
    end
    
    def sum_samples_at_least(min, sum, k)
      cut = min-1
      samples_for_sum(sum-k*cut, k)
        .map{|i| i+cut}
    end
    
    all = sum_samples_at_least(4,80,10)
    p all, all.inject(:+)
    
    
  • Object 定义的方法求解答 at 2014年12月19日

    是的,上面说的都很清楚了。

    x = Object.new
    x.do_it #=> 就会去x的类里(也就是Object里)找do_it方法
    
    Object.do_it #=>就会去Object的类里,也就是 Class里找do_it,因为找不到就会去Class的超类也就是Object里找do_it
    
    1. Ruby MRI为了线程安全,用了GIL只支持单核。任何时刻只有一个线程在运行:当一个Thread阻塞时(比如IO, sleep等),就会切换到另个一线程。 所以就算用了celluloid, puma自动创建多线程的,MRI下每个进程还是单核。
    2. 而Rubinius,JRuby则没有GIL,支持多核(每个线程分配一个cpu)。
    3. 如果MRI下要用多核,就要用sidekiq之类的跑多个worker进程。
    4. 单核不一定比多核慢,很多时候瓶颈不在CPU,而MRI多线程可以保证IO并发,所以性能可能是一样的。
    5. 多进程消耗内存,而且进程间难以通信(只能通过IO之类的)。多线程,直接共享变量(内存)。
  • 既然知道类,为什么不直接用实例或者直接定义成类方法呢? klass.new.foo

    class C
      def bar; 'instance bar' end
      def baz; 'instance baz' end
    end
    
    class C
      def self.become_evil(*names)
        obj = new
        names.each{|name| define_singleton_method(name, &obj.method(name.to_sym))}
      end
    
      become_evil :baz, :bar
    end
    
    C.bar
    C.baz
    
  • lambda binding 的一些行为 at 2014年12月12日

    #8楼 @cicholgricenchos 呵呵,应该是的,我也不是太确定。。。

    运行到定义proc代码的时候,把当时的本地变量表从stack复制一份到heap上,然后让这个proc引用它。所以后边再声明的变量都不会加到这个heap复制表(而是加到stack上),所以新加的变量都找不到。

    然后,应该是直接编译成类似self.send(:b)了,而不是运行时才查询变量表链,这样效率挺高的。

  • lambda binding 的一些行为 at 2014年12月12日

    哈哈,推荐这本书,配图讲的比较清楚,我看完后比以前明白了一点。

    1. closure(包括block, proc, lambda)语法作用域是绑定死的,动态的部分只有参数表和self(通过instance_eval等改变)。
    2. 执行一个proc的时候,先检查lexical_scope_chain每个本地变量表,如果没有再检查当前self的方法表。
    3. 创建proc时,只会到绑定当时的变量表(会把当时的变量表复制到堆上,再引用),所以之后定义的变量都看不到;但是方法表是通过self在运行时找的,所以之后定义的方法可以看到。
    4. binding只能取得proc的语法作用域,不能修改
    b = lambda{ p local_variables }
    a = lambda { |b|
      c = 1
      (lambda &b).call
    }
    p a.call(b) 
    #=>等价于
    p b.call
    #=>等价于
    p self.send(:local_variables) 
    
    a = lambda{ p b } #这里只绑定了此时此刻的变量表(链),所以它永远看不到b变量,所以会编译成self.send(:b)
    b = 1
    a.call    #这里才执行self.send(:b),但是当前self没有b方法
    
    a = lambda{ p b } # 这里编译时先找变量b找不到,所以会编译成执行self.send(:b)
    def b
      1
    end
    a.call # => 1   #这里才执行self.send(:b),所以没问题
    
  • *** extconf.rb failed *** Could not create Makefile due to some reason, probably lack of necessary libraries and/or headers. Check the mkmf.log file for more details. You may need configuration options.

    检查下mkmf.log错误报告,也可以去stackoverflow搜看看..

  • 没有啊,引号在双引号里会转义的:"\"...\"" 可以用File.foreach:

    result = File.foreach(filename,encoding:'utf-8').map{|line| line[/([^(]+)/,1]}
    
  • sidekiq 发邮件的诡异问题 at 2014年12月10日

    检查下from地址写全了么?比如:

    default from: "your_username@mail_host.com"