Static Code Analysis For Ruby
Upcoming SlideShare
Loading in...5
×
 

Static Code Analysis For Ruby

on

  • 4,445 views

This is my presentation on Shanghai on Rails at 3.20. It introduces static code analysis for ruby, tells you a pattern to analysis ruby code and gives you some examples that how rails_best_practices ...

This is my presentation on Shanghai on Rails at 3.20. It introduces static code analysis for ruby, tells you a pattern to analysis ruby code and gives you some examples that how rails_best_practices analysis rails codes.

Statistics

Views

Total Views
4,445
Views on SlideShare
4,313
Embed Views
132

Actions

Likes
9
Downloads
52
Comments
0

10 Embeds 132

http://www.huangzhimin.com 75
http://feeds.feedburner.com 31
http://huangzhimin.com 9
http://www.slideshare.net 7
http://paper.li 3
http://flyerhzm.github.com 2
http://www.linkedin.com 2
http://github.chunchu.org 1
http://coderwall.com 1
http://flyerhzm.github.io 1
More...

Accessibility

Categories

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Static Code Analysis For Ruby Static Code Analysis For Ruby Presentation Transcript

  • Static Code Analysis for Ruby Richard Huang E kohe www.ekohe.com Web Development & Graphic Design China Ruby on Rails Development - Rails Consulting - Rails Services - Merb - Offshore Web Development
  • 有没有对 Ruby 代码进行过静态分析? www.ekohe.com Web Development & Graphic Design China Ruby on Rails Development - Rails Consulting - Rails Services - Merb - Offshore Web Development
  • 案例 www.ekohe.com Web Development & Graphic Design China Ruby on Rails Development - Rails Consulting - Rails Services - Merb - Offshore Web Development
  • 有没有看过张文钿的演讲稿 Rails Best Practices ? http://www.slideshare.net/ihower/rails-best-practices www.ekohe.com Web Development & Graphic Design China Ruby on Rails Development - Rails Consulting - Rails Services - Merb - Offshore Web Development
  • 有没有使用过 rails_best_practices gem ? http://github.com/flyerhzm/rails_best_practices www.ekohe.com Web Development & Graphic Design China Ruby on Rails Development - Rails Consulting - Rails Services - Merb - Offshore Web Development
  • 静态分析 VS 动态分析
    • 整体 VS 局部
    • 粗略 VS 精确
    www.ekohe.com Web Development & Graphic Design China Ruby on Rails Development - Rails Consulting - Rails Services - Merb - Offshore Web Development
  • 静态分析什么? 源程序? www.ekohe.com Web Development & Graphic Design China Ruby on Rails Development - Rails Consulting - Rails Services - Merb - Offshore Web Development
  • 抽象语法树 (AST)
    • a = b * c + b * c
    www.ekohe.com Web Development & Graphic Design China Ruby on Rails Development - Rails Consulting - Rails Services - Merb - Offshore Web Development assign a * + * b b c c
  • s-expression www.ekohe.com Web Development & Graphic Design China Ruby on Rails Development - Rails Consulting - Rails Services - Merb - Offshore Web Development s(:class, :Student, nil, s(:scope, s(:block, s(:call, nil, :attr_accessor, s(:arglist, s(:lit, :name)) ), s(:defn, :initialize, s(:args, :name), s(:scope, s(:block, s(:iasgn, :@name, s(:lvar, :name)) ) ) ) ))) class Student attr_accessor :name def initialize(name) @name = name end end
  • s-expression www.ekohe.com Web Development & Graphic Design China Ruby on Rails Development - Rails Consulting - Rails Services - Merb - Offshore Web Development s(:defn, :output, s(:args, :arg1, :arg2), s(:scope, s(:block, s(:if, s(:call, s(:lvar, :arg1), :==, s(:arglist, s(:str, "hello")) ), s(:call, nil, :print, s(:arglist, s(:lvar, :arg1), s(:lvar, :arg2)) ), s(:call, nil, :print, s(:arglist, s(:lvar, :arg1)) ) ) ) ) ) def output(arg1, arg2) if arg1 == 'hello' print arg1, arg2 else print arg1 end end
  • s-expression 的特点
    • 类树(继承数组)
    • 结构清晰
    • 方便解析
    www.ekohe.com Web Development & Graphic Design China Ruby on Rails Development - Rails Consulting - Rails Services - Merb - Offshore Web Development
  • 如何生成 s-expression www.ekohe.com Web Development & Graphic Design China Ruby on Rails Development - Rails Consulting - Rails Services - Merb - Offshore Web Development ruby 源代码 s-expression ruby_parser ruby2ruby
  • 如何解析 s-expression ?
    • Visitor Pattern
    • 优点:
      • 数据结构与访问类分离
      • 方便地增加访问类
    • 缺点:
      • 增加数据类型很麻烦
      • 访问类只能处理当前结点
    www.ekohe.com Web Development & Graphic Design China Ruby on Rails Development - Rails Consulting - Rails Services - Merb - Offshore Web Development
  • rails_best_practices 是如何做静态代码分析的? www.ekohe.com Web Development & Graphic Design China Ruby on Rails Development - Rails Consulting - Rails Services - Merb - Offshore Web Development
  • rails_best_practices www.ekohe.com Web Development & Graphic Design China Ruby on Rails Development - Rails Consulting - Rails Services - Merb - Offshore Web Development rails_best_practices 结果输出 代码检查类 代码解析器 配置 源代码 5. 代码检查 2. 生成检查类集合 3. 分析源代码 4. 生成 s-expression 1. 读取配置 6. 显示检查结果
  • 代码解析
    • 解析顺序
    www.ekohe.com Web Development & Graphic Design China Ruby on Rails Development - Rails Consulting - Rails Services - Merb - Offshore Web Development model files migration files controller files helper files view files …… migration files
  • 代码解析 www.ekohe.com Web Development & Graphic Design China Ruby on Rails Development - Rails Consulting - Rails Services - Merb - Offshore Web Development erb files haml files ruby files src precompiled ruby_parser s-expression
  • 代码检查 www.ekohe.com Web Development & Graphic Design China Ruby on Rails Development - Rails Consulting - Rails Services - Merb - Offshore Web Development s-expression class defn call Check UseModelAssociationCheck MoveFinderToNamedScopeCheck if UseScopeAccessCheck LawOfDemeterCheck
  • 代码检查
    • Visitor Pattern 扩展
      • 不仅关注结点的类型
      • 而且关注结点所在的文件
    www.ekohe.com Web Development & Graphic Design China Ruby on Rails Development - Rails Consulting - Rails Services - Merb - Offshore Web Development
  • rails_best_practices 做静态代码分析的 一些 思路 www.ekohe.com Web Development & Graphic Design China Ruby on Rails Development - Rails Consulting - Rails Services - Merb - Offshore Web Development
  • ReplaceInstanceVariableWithLocalVariableCheck
    • # app/views/posts/_post.html.erb
    • <%= @post.title %>
    • <%= @post.body %>
    www.ekohe.com Web Development & Graphic Design China Ruby on Rails Development - Rails Consulting - Rails Services - Merb - Offshore Web Development
  • ReplaceInstanceVariableWithLocalVariableCheck
    • # app/views/posts/_post.html.erb
    • <%= @post.title %>
    • 在 partial 文件中任何类型为 ivar 的结点 都违反
    www.ekohe.com Web Development & Graphic Design China Ruby on Rails Development - Rails Consulting - Rails Services - Merb - Offshore Web Development ivar s(:call, s(:ivar, :@post), :title, s(:arglist))
  • MoveFinderToNamedScopeCheck
    • class PostsController < ApplicationController
    • def index
    • @published_posts = Post.find(:all, :limit => 10, :order => ‘created_at desc’)
    • end
    • end
    www.ekohe.com Web Development & Graphic Design China Ruby on Rails Development - Rails Consulting - Rails Services - Merb - Offshore Web Development
  • MoveFinderToNamedScopeCheck
    • Post.find(:all, :limit => 10, :order => ‘created_at desc’)
    • 在 controller 文件中 find, all, first, last 方法带类型为 hash 的参数的都违反
    www.ekohe.com Web Development & Graphic Design China Ruby on Rails Development - Rails Consulting - Rails Services - Merb - Offshore Web Development const find, all, first, last hash s(:call, s(:const, :Post), :find, s(:arglist, s(:lit, :all), s(:hash, s(:lit, :limit), s(:lit, 10), s(:lit, :order), s(:str, &quot;created_at desc&quot;)) ) )
  • AddModelVirtualAttributeCheck
    • class UsersController < ApplicationController
    • def create
    • @user = User.new(params[:user])
    • @user.first_name = params[:full_name].split(‘ ‘, 2).first
    • @user.last_name = params[:full_name].split(‘ ‘, 2).last
    • @user.save
    • end
    • end
    www.ekohe.com Web Development & Graphic Design China Ruby on Rails Development - Rails Consulting - Rails Services - Merb - Offshore Web Development
  • AddModelVirtualAttributeCheck
    • @user.first_name = params[:full_name].split(‘ ‘, 2).first
    • attrassign
    • @user.last_name = params[:full_name].split(‘ ‘, 2).last
    • attrassign
    • @user.save
    • 对于一个 variable ,如果接收到两条不同的赋值消息,但参数的 &quot; 首部分 &quot; 是相同的,那么它就违反
    www.ekohe.com Web Development & Graphic Design China Ruby on Rails Development - Rails Consulting - Rails Services - Merb - Offshore Web Development mesage arguments whose message is [] mesage arguments whose message is []
  • LawOfDemeterCheck
    • class Invoice < ActiveRecord::Base
    • belongs_to :user
    • end
    • <%= @invoice.user.name %>
    www.ekohe.com Web Development & Graphic Design China Ruby on Rails Development - Rails Consulting - Rails Services - Merb - Offshore Web Development
  • LawOfDemeterCheck
    • class Invoice < ActiveRecord::Base
    • belongs_to :user
    • end
    • <%= @invoice.user.name %>
    • app/models/*.rb 必须首先被解析
    • 如果 variable 的名字和 model 的 class name 匹配,同时调用的消息名和 association 名字相同,则违反
    www.ekohe.com Web Development & Graphic Design China Ruby on Rails Development - Rails Consulting - Rails Services - Merb - Offshore Web Development message class name association name
  • AlwaysAddDbIndexCheck
    • class CreateComments < ActiveRecord::Migration
    • def self.up
    • create_table :comments do |t|
    • t.string :content
    • t.integer :post_id
    • t.integer :user_id
    • end
    • end
    • end
    www.ekohe.com Web Development & Graphic Design China Ruby on Rails Development - Rails Consulting - Rails Services - Merb - Offshore Web Development
  • AlwaysAddDbIndexCheck
    • create_table :comments do |t|
    • t.string :content
    • t.integer :post_id
    • t.integer :user_id
    • end
    • add_index :comments, :post_id
    • db/migrations/*.rb 必须被解析两次
    • 所有 create_table 中创建的外键没有出现在 add_index 的参数中,那么它就违反
    www.ekohe.com Web Development & Graphic Design China Ruby on Rails Development - Rails Consulting - Rails Services - Merb - Offshore Web Development table name integer with _id column with _id and integer references
  • AlwaysAddDbIndexCheck
    • What about?
    • [[:comments, :post_id], [:comments, :user_id]].each do |args|
    • add_index *args
    • end
    www.ekohe.com Web Development & Graphic Design China Ruby on Rails Development - Rails Consulting - Rails Services - Merb - Offshore Web Development
  • AlwaysAddDbIndexCheck
    • Ruby2Ruby.new.process(node)
    • 模拟 add_index ,动态处理
    • Ruby is Powerful!
    www.ekohe.com Web Development & Graphic Design China Ruby on Rails Development - Rails Consulting - Rails Services - Merb - Offshore Web Development def add_index(*args) table_name, column_names = *args table_name = table_name.to_s # call AlwaysAddDbIndexCheck method end
  • 静态代码分析 代码检查 代码重构 www.ekohe.com Web Development & Graphic Design China Ruby on Rails Development - Rails Consulting - Rails Services - Merb - Offshore Web Development
  • Q&A Thank you Website: http://www.huangzhimin.com Github: http://github.com/flyerhzm www.ekohe.com Web Development & Graphic Design China Ruby on Rails Development - Rails Consulting - Rails Services - Merb - Offshore Web Development