GitXplorerGitXplorer
a

detective

public
15 stars
1 forks
0 issues

Commits

List of commits on branch master.
Unverified
507e125f293d10b8238dff2f362ff3deeb342032

Added support to method_missing

aaseldawy committed 15 years ago
Unverified
11aa943ad8228b855cfc76ef19c168c14b46d1fc

Version bump to 0.3.0

aaseldawy committed 15 years ago
Unverified
5fa06883338bf45a63397b33eb97961507887b95

Fixed a type in Readme

aaseldawy committed 15 years ago
Unverified
757416a65dae528c7012c9dcf10f5f13541b7321

Added installation section to README file

aaseldawy committed 15 years ago
Unverified
3b539d57c849921d693f7abd726c509f1a194019

Solved a bug with Processes

aaseldawy committed 15 years ago
Unverified
6faff91bf28e7e9f9b128cada1558fe77b8c8df3

Version bump to 0.2.0

aaseldawy committed 15 years ago

README

The README file for this repository.

= detective

Detective is a gem built by BadrIT (http://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

Copyright (c) 2009 BadrIT. See LICENSE for details.