Code Monkey home page Code Monkey logo

detective's Introduction

detective

Detective is a gem built by BadrIT (www.badrit.com/) to investigate the ruby source code. Check the examples below.

Motivation

Tired of opening files of installed gems to know how the code is working? Not able to know who and where that function has been overrided? It’s time to get help from a private Detective. Detective allows you show the source and find the location of some ruby method.

Installation

gem install detective

Examples

View the source of a class method …

require 'detective'

Detective.view_source('ActiveRecord::Base.find_by_sql')

Result

def find_by_sql(sql)
  connection.select_all(sanitize_sql(sql), "#{name} Load").collect! { |record| instantiate(record) }
end

View the source of an instance method …

Detective.view_source('ActiveRecord::Base#update_attributes')

Result

def update_attributes(attributes)
  self.attributes = attributes
  save
end

View the source of an overrided method …

ActiveRecord::Base.class_eval do
  def update_attributes(attributes)
    puts "updating attributes ..."
    self.attributes = attributes
    save
  end
end

Detective.view_source('ActiveRecord::Base#update_attributes')

Result

def update_attributes(attributes)
  puts "updating attributes ..."
  self.attributes = attributes
  save
end

Find the location of some source …

Detective.get_location('ActiveRecord::Base#attributes')

Result

location
/home/aseldawy/.gem/ruby/1.8/gems/activerecord-2.3.4/lib/active_record/base.rb
2752

(new) You can also find source code for modules …

Detective.view_source('AuthenticatedSystem#current_user')

Result

def current_user
  @current_user ||= (login_from_session || login_from_basic_auth || login_from_cookie) unless @current_user == false
end

(new) You have an alternative output …

Detective.view_source('AuthenticatedSystem#current_user', :rdoc)

Result

/home/aseldawy/aptana_studio/archiving_system/lib/authenticated_system.rb, line 11
11:    def current_user
12:      @current_user ||= (login_from_session || login_from_basic_auth || login_from_cookie) unless @current_user == false
13:    end

(new) Detective is now also working with method_missing …

Detective.view_source('ActiveRecord::Base#find_by_id')

Result

def method_missing(method_id, *args, &block)
  method_name = method_id.to_s

  if self.class.private_method_defined?(method_name)
    raise NoMethodError.new("Attempt to call private method", method_name, args)
  end

  # If we haven't generated any methods yet, generate them, then
  # see if we've created the method we're looking for.
  if !self.class.generated_methods?
    self.class.define_attribute_methods
    if self.class.generated_methods.include?(method_name)
      return self.send(method_id, *args, &block)
    end
  end

  if self.class.primary_key.to_s == method_name
    id
  elsif md = self.class.match_attribute_method?(method_name)
    attribute_name, method_type = md.pre_match, md.to_s
    if @attributes.include?(attribute_name)
      __send__("attribute#{method_type}", attribute_name, *args, &block)
    else
      super
    end
  elsif @attributes.include?(method_name)
    read_attribute(method_name)
  else
    super
  end
end

No luck with native methods …

Detective.view_source('String#length')

Result

native method

How it works (advanced)

The idea is to invoke the given method and trace the execution of the program. This allows us to know where is the definition of the method. Then with the help of RubyParser, we can extract its code from the file. The invoke of this method is made in a separate process so that it doesn’t conflict with your program. This child process is killed before the method starts its execution so the method is not really invoked.

For systems not supporting fork (like windows), the child process is replaced with a thread. This might make some problems because it is running in the same space of your own ruby program. We make our best to decrease the effect of this call by killing the thread before the method starts execution. However, given that Detective will be used while developing only, we can ignore this effect.

Copyright © 2009 BadrIT. See LICENSE for details.

detective's People

Contributors

aseldawy avatar

Stargazers

Angus H. avatar Hiroshi Minoshima avatar Ahmed Kotb avatar  avatar sandeep kumar avatar kayak avatar Tom Lehman avatar Jits avatar Mahmoud Salem avatar Clément Joubert avatar Deepak Kannan avatar  avatar Fabio Akita avatar Felipe Coury avatar George avatar

Watchers

 avatar  avatar

Forkers

badrit

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.