• 刚把 512 升到 1024 了,单独跑 rails 是够的,装了个 php+wordpress 一起跑就不够了……

  • 代码优化 at 2013年05月03日
    err = '操作错误!'  if topic.nil?
    err = '操作错误1!' if topic1.nil?
    err = '操作错误2!' if topic2.nil?
    
    redict_to params[:rt], notice: err if err
    

    代码还有些问题:

    1. 貌似是用 rails 的,推荐用 blank? 代替 nil?
    2. redirect_to_params[:rt] 可能有安全漏洞
  • Linode - This IP has been banned. at 2013年05月02日

    点了一下,我也是啊

  • 楼主 4 月 25 发的几个问题都被扣成负分了……

    有人问:楼主你自己试过了什么解决方案了吗?(What have you tried?) 楼主回答:我试了一整天了!(i try it by one days) 真为楼主捉急啊。。

    http://stackoverflow.com/questions/16210183/how-can-i-implement-scroll-like-goodnotes 楼主这个问题就说我要做什么什么,要实现什么什么效果。 然后呢?就没有然后了 别人当然会问,你遇到什么问题了啊?你自己尝试了什么解决方案呢?你说出来才好帮你 楼主答:要是你懂中文我就可以告诉你! 老外就吐血了……

    The problem is, we don't write apps for you. We help you solves specific problems, and you don't have specific problems because you don't appear to have tried anything

    这还真不只是语法问题啊,楼主补习一下《提问的智慧》吧 语法错误之类的不要紧,别人能猜到。可是你不写具体什么问题,别人没法帮你

  • system( 'cls' ) || system( 'clear' ) || system( "cmd", "/c", "cls" )
    

    猜的,没试过

  • #30 楼 @luikore 奇怪,我在 linux 下运行会报这个语法错误:

    ➜  ~  ruby -v
    ruby 2.1.0dev (2013-04-26) [x86_64-linux]
    ➜  ~  ruby test.rb
                              test.rb:21:in `block (2 levels) in <main>': wrong number of arguments (0 for 1) (ArgumentError)
        from test.rb:29:in `[]'
        from test.rb:29:in `block (2 levels) in <main>'
        from test.rb:29:in `times'
        from test.rb:29:in `each'
        from test.rb:29:in `map'
        from test.rb:29:in `block in <main>'
        from test.rb:26:in `loop'
        from test.rb:26:in `<main>'
    ➜  ~  uname -a
    Linux qhwa-laptop 3.2.0-40-generic #64-Ubuntu SMP Mon Mar 25 21:22:10 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux
    
  • 原因很多,可以写一本书 http://book.douban.com/subject/4786109/

    几年前有幸听过作者的讲座,很折服。 结合最近的所见所想,个人认为宗教方面的原因最重要

  • 挖个坟 @iBachue

    在读 rails 的源码,刚好看到了 ActiveSupport::Concern,里面同时用了这两个方法 https://github.com/rails/rails/blob/master/activesupport/lib/active_support/concern.rb#L105-L124

    对照了一下 ruby 文档,append_features 更底层一些,通过重写可以阻止 ruby 默认的逻辑——添加常量、方法和 module variables 到目标类中。而 included 只是一个 hook。

    ActiveSupport::Concern 用了 append_features 来保证继承链能统一作用到最终目标类上。不知道我理解的对不对?

  • 拜读营养帖

  • google 了一下,这个 stackoverflow 上的问题 应该和你需求类似

  • 如何与程序员沟通 at 2013年04月19日

    对极了。。

  • #33 楼 @donnior 握爪,学习~

  • #!/usr/bin/env ruby
    # encoding: utf-8
    #copy tag from test env to prod env
    require 'mysql2'
    class TagCopy
    
      def initialize
        @from_db = Mysql2::Client.new(
          :host     => "192.168.xx.xx", 
          :port     => 3306, 
          :username => "mysql", 
          :password => "mysql", 
          :database => "mydb"
        )
        @to_db = Mysql2::Client.new(
          :host     => "192.168.xx1.xx2", 
          :port     => 3306, 
          :username => "root",
          :password => "root", 
          :database => "mydb"
        )
      end
    
      # 将 get_tags_by_key 改名为 migrate_tags_by_key
      # 原因是: get_xxxx 约定中都是读取操作,不会
      # 修改数据,无论 get 多少次,都不会引起副作用
      # 不适合这里的功能
      def migrate_tags_by_key( tag_key )
        #escape param to defend sql injection
        param = @from_db.escape(tag_key)
    
        # 我觉得 select * 在这里就足够了,等性能有问题了再考虑优化
        sql = "SELECT * FROM tbl_cms_tags where tag_key = '#{param}'";
        puts sql
    
        results = @from_db.query(sql)
        puts "total #{results.count} records "
    
        results.each do |row|
          # 这里将 uuid 查询,root_id 重构成了一个方法
          # 方便阅读。同时带来额外的好处:在其他方法中
          # 可以重用这个逻辑了
    
          # 为什么叫 new_parent_id 而不是 new_pid ?
          # 因为 pid 大家已经习惯了是 process id
          add_tag( row, new_parent_id, first_sql_root_id)
    
          if has_children?(row)
            migrate_children( new_parent_id, row['id'] )
          end
        end
      end
    
      # 注意到了没, add_tag 现在在 migrate_children 之前
      # 定义? 是因为 migrate_tags_by_key 方法中先调用了
      # add_tag 方法。函数的定义顺序遵循他们出现的顺序,
      # 让后面的维护者更通顺地阅读
      def add_tag(row, id, parent_id)
        row = row.dup
        row["site"]     ||= 0
        row["row_num"]  ||= 1
        row["sort_no"]  ||= 0
    
        # 把你需要的属性列在这里,不要去重复写
        # 两遍属性。原先的SQL很容易写错,这样写
        # 就不容易犯错,出错了也很容易辨认
        attrs = %w[ 
            id          no          tag_key 
            tag_name    tag_url     tag_desc 
            structure   type        isleaf 
            child       level       brand_no 
            category_no channel_no  other_no 
            row_num     site        sort_no 
            ad_quantity image_size  parent_id 
            enable_more
        ]
    
        values = attrs.map {|attr| row[attr] }
    
        # 这样写,这条sql语句就没有那么可怕了
        # 如果一行代码超过了70个字符,很危险的标志
        insert_sql = <<-SQL 
          INSERT INTO yitian_b2c_db.tbl_cms_tags
            (#{attrs.join ','})
            VALUES
            (#{values.join ','})
          SQL
    
        puts insert_sql
        @to_db.query(insert_sql)
      end
    
      def migrate_children( new_parent_id, parent_id)
        sql = "SELECT * FROM tbl_cms_tags where parent_id = '#{parent_id}'";
    
        @from_db.query(sql).each do |row|
          add_tag(row, new_parent_id, new_parent_id)
          if has_children?(row)
            migrate_children( new_parent_id, row["id"])
          end
        end
      end
    
      def cleanup
        @from_db.close
        @to_db.close
      end
    
      private
    
        def uuid
          q = "SELECT REPLACE(UUID(),'-','')"
          @uuid ||= @to_db.query( q, :as => :array).first
        end
    
        def new_parent_id
          uuid.first
        end
    
        def first_sql_root_id
          sql_root_id.first
        end
    
        def sql_root_id
          q = "select id from tbl_cms_tags where tag_key ='ol_main'"
          @sql_root_id ||= @to_db.query( q ).first
        end
    
        def has_children?(row)
          row['child'] > 0
        end
    
    end
    
    if __FILE__ == $0
      tc = TagCopy.new
      tc.migrate_tags_by_key "ol_index"
    
      # 将 close 单独独立成一个方法
      # 本意是使核心方法更加简洁, 发现带来了额外的好处:
      # 这个类现在可以支持一次migrate多个任务
      tc.cleanup
    end
    
    

    对于核心数据结构不是很清楚,只做了些语言层面的重构

  • 简单吐槽 at 2013年04月11日

    哈哈,生活中特别不靠谱,我也有点,已被夫人批评无数次 可能他在西藏? :D

  • 吐槽一下注释 at 2013年04月09日

    我们就以 shopqi 为例,纯粹技术探讨哈

    https://github.com/saberma/shopqi/blob/master/app/models/shop.rb#L193

    after_destroy do # 删除对应的目录
      FileUtils.rm_rf self.path
      FileUtils.rm_rf self.public_path
    end
    
    protected
    def init_valid_date
      self.deadline = Date.today.advance months: 1 unless self.plan_free?
    end
    
    def init_currency
      self.currency ||= 'CNY' # 初始化为人民币
      set_currency_format
    end
    
    def set_currency_format # 设置币种显示格式
      data = KeyValues::Shop::Currency.find_by_code(currency)
      self.money_with_currency_format           = data.html_unit
      self.money_format                         = data.html
      self.money_with_currency_in_emails_format = data.email_unit
      self.money_in_emails_format               = data.email
    end
    

    这里 3 个注释都在解释代码做了什么,说明有优化的空间

    我会这样改:

    after_destroy :rm_directories
    
    protected
    
      def rm_directories
        FileUtils.rm_rf self.path
        FileUtils.rm_rf self.public_path
      end
    
      def init_valid_date
        self.deadline = Date.today.advance months: 1 unless self.plan_free?
      end
    
      def init_currency
        self.currency ||= 'CNY'
        set_currency_format
      end
    
      def set_currency_display_format
        data = KeyValues::Shop::Currency.find_by_code(currency)
        self.money_with_currency_format           = data.html_unit
        self.money_format                         = data.html
        self.money_with_currency_in_emails_format = data.email_unit
        self.money_in_emails_format               = data.email
      end
    
      # 这里用 alias_method 向前兼容
      alias_method :set_currency_format, 
                   :set_currency_display_format
    

    最后一个注释是解释 为什么

  • 吐槽一下注释 at 2013年04月09日

    #8 楼 @ghjcumt2008 我说的是:在注释里面描述对应的代码在做什么,是一种坏味道

    没人说不需要注释。但在你开始注释之前,再审视一遍。

    https://github.com/bbatsov/ruby-style-guide#comments http://blog.csdn.net/horkychen/article/details/6322152

    接下来的讨论希望能有代码范例,否则很空的。

  • 吐槽一下注释 at 2013年04月09日

    #3 楼 @dotnil 一句话概括了我的一段话,精辟

  • 吐槽一下注释 at 2013年04月09日

    代码所呈现的是:以什么样的方式,完成了什么功能 注释所补充的是代码无法呈现的信息,比如“为什么要这样”,“为什么要以这种方式”

    如果注释在描述“做了什么”,是一种代码坏味道,因为说明代码不够清晰了,就会导致

    回头看以前代码的时候觉的累

    以这种思路去实践,开发时更多的是代码重构,而不是加注释。

  • Ruby China 帖子过万啦 at 2013年04月07日

  • 用 google,而且用英文关键字搜,可以很快找到问题答案 百度?满眼都是一模一样的、几年前写的老文章

  • let codes talk http://todomvc.com/

  • Any ruby geek in Xiamen? at 2013年03月28日

    过年去厦门玩了,印象很好:空气好,交通好,有各种好吃的,周末还可以去海边骑骑车,很惬意的感觉~

  • 终于,破 200 了…… at 2013年03月27日

    Good for u! 😀

  • Teahour.fm 第 8 期发布 at 2013年03月27日

    支持,teahour 很棒,加油!

  • Rails Assets Pipeline 的价值 at 2013年03月23日

    asset pipeline 不能和 grunt、require.js、spm 共存?因为我还没有开始做单页面的应用,所以还没有尝试。但我觉得应该可以共存的。

    1. asset pipeline 也是调用 js 解析器的,其中一个常见的就是 nodejs。理论上扩展一下没什么难度。
    2. 以 grunt 为例,你可以修改 application.js,保存的瞬间立刻帮你生成编译好的。rails 接着要做的很简单,就是 copy 一下,md5 一下,done!
    3. 我试过 less 用 asset pipeline 的 require 语法,混用 less 自身的 @import 语法,完全没有问题

    不管怎么说,我觉得前端方案肯定是能在 rails 里面 work 的,等我做单页应用的时候玩玩

  • crontab 执行 ruby 脚本 at 2013年03月23日

    #9 楼 @tiseheaini 当年也是这些坑一个个趟过来的,你总结得挺好的 有一段时间会写 crontab 时特别小心,一步一步测试,每天运行一次的脚本,也要先设置成每分钟运行,看看有没有效果。其实精力是没必要浪费在这上面的