BMorearty-looksee 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/.autotest ADDED
@@ -0,0 +1,9 @@
1
+ Autotest.add_hook :initialize do |at|
2
+ at.add_mapping(/ext\/.*\/(.*)\.[ch]/) do |_, m|
3
+ ["test/test_#{m[1]}_extn.rb"]
4
+ end
5
+ end
6
+
7
+ Autotest.add_hook :run_command do |at|
8
+ system "rake compile"
9
+ end
data/History.txt ADDED
@@ -0,0 +1,18 @@
1
+ == 0.1.1 2009-08-27
2
+
3
+ * Add colors method and lc shortcut.
4
+
5
+ == 0.1.0 2009-08-20
6
+
7
+ * Add methods undefined with Module#undef_method. Blue by default.
8
+
9
+ == 0.0.2 2009-07-28
10
+
11
+ * Added #grep to filter methods shown: lp(object).grep(/pattern/)
12
+ * Fix #1: Play nice with Wirble.
13
+ * Fix #3: Don't die when examining immediate objects (fixnum, symbol,
14
+ true, false, nil)
15
+
16
+ == 0.0.1 2009-07-05
17
+
18
+ * Hi.
data/Manifest.txt ADDED
@@ -0,0 +1,21 @@
1
+ .autotest
2
+ History.txt
3
+ Manifest.txt
4
+ README.rdoc
5
+ Rakefile
6
+ ext/looksee/extconf.rb
7
+ ext/looksee/looksee.c
8
+ ext/looksee/node-1.9.h
9
+ lib/looksee.rb
10
+ lib/looksee/shortcuts.rb
11
+ lib/looksee/version.rb
12
+ lib/looksee/wirble_compatibility.rb
13
+ looksee.gemspec
14
+ script/console
15
+ script/destroy
16
+ script/generate
17
+ spec/looksee_spec.rb
18
+ spec/spec_helper.rb
19
+ spec/wirble_compatibility_spec.rb
20
+ tasks/extconf.rake
21
+ tasks/extconf/looksee.rake
data/README.rdoc ADDED
@@ -0,0 +1,129 @@
1
+ = Looksee
2
+
3
+ * http://github.com/oggy/looksee
4
+
5
+ == DESCRIPTION
6
+
7
+ Looksee lets you examine the method lookup path of objects in ways not
8
+ possible in plain ruby.
9
+
10
+ == SYNOPSIS
11
+
12
+ Pop this in your .irbrc :
13
+
14
+ require 'looksee/shortcuts'
15
+
16
+ This defines a method +lp+ ("lookup path") which lets you do:
17
+
18
+ irb(main):001:0> lp []
19
+ => Array
20
+ & concat frozen? push taguri
21
+ * count hash rassoc taguri=
22
+ + cycle include? reject take
23
+ - delete index reject! take_while
24
+ << delete_at indexes replace to_a
25
+ <=> delete_if indices reverse to_ary
26
+ == drop insert reverse! to_s
27
+ [] drop_while inspect reverse_each to_yaml
28
+ []= each join rindex transpose
29
+ assoc each_index last select uniq
30
+ at empty? length shift uniq!
31
+ choice eql? map shuffle unshift
32
+ clear fetch map! shuffle! values_at
33
+ collect fill nitems size yaml_initialize
34
+ collect! find_index pack slice zip
35
+ combination first permutation slice! |
36
+ compact flatten pop sort
37
+ compact! flatten! product sort!
38
+ Enumerable
39
+ all? each_slice first min reverse_each
40
+ any? each_with_index grep min_by select
41
+ collect entries group_by minmax sort
42
+ count enum_cons include? minmax_by sort_by
43
+ cycle enum_slice inject none? take
44
+ detect enum_with_index map one? take_while
45
+ drop find max partition to_a
46
+ drop_while find_all max_by reduce zip
47
+ each_cons find_index member? reject
48
+ Object
49
+ taguri taguri= to_yaml to_yaml_properties to_yaml_style
50
+ Kernel
51
+ == hash object_id
52
+ === id private_methods
53
+ =~ inspect protected_methods
54
+ __id__ instance_eval public_methods
55
+ __send__ instance_exec respond_to?
56
+ class instance_of? send
57
+ clone instance_variable_defined? singleton_methods
58
+ display instance_variable_get taint
59
+ dup instance_variable_set tainted?
60
+ enum_for instance_variables tap
61
+ eql? is_a? to_a
62
+ equal? kind_of? to_enum
63
+ extend method to_s
64
+ freeze methods type
65
+ frozen? nil? untaint
66
+
67
+ It'll also color the methods according to whether they're public,
68
+ protected, private, undefined (using Module#undef_method), or
69
+ overridden. So pretty. You gotta try it. The default colors are:
70
+
71
+ public: green
72
+ protected: yellow
73
+ private: red
74
+ undefined: blue
75
+ overridden: black
76
+
77
+ To remind yourself what each looksee color means in irb:
78
+
79
+ lc
80
+
81
+ By default, it shows public and protected methods. Add private ones
82
+ like so:
83
+
84
+ lp [], :private => true
85
+ lp [], :private # shortcut
86
+
87
+ Or if you don't want protected:
88
+
89
+ lp [], :protected => false
90
+
91
+ There are variations too. And you can configure things. And you can
92
+ use it as a library without polluting the built-in classes. See:
93
+
94
+ $ ri Looksee
95
+
96
+ Enjoy!
97
+
98
+ == INSTALL
99
+
100
+ gem install looksee
101
+
102
+ == FEATURES/PROBLEMS
103
+
104
+ * Currently only does MRI 1.8, 1.9.
105
+
106
+ == LICENSE
107
+
108
+ (The MIT License)
109
+
110
+ Copyright (c) 2009 George Ogata
111
+
112
+ Permission is hereby granted, free of charge, to any person obtaining
113
+ a copy of this software and associated documentation files (the
114
+ 'Software'), to deal in the Software without restriction, including
115
+ without limitation the rights to use, copy, modify, merge, publish,
116
+ distribute, sublicense, and/or sell copies of the Software, and to
117
+ permit persons to whom the Software is furnished to do so, subject to
118
+ the following conditions:
119
+
120
+ The above copyright notice and this permission notice shall be
121
+ included in all copies or substantial portions of the Software.
122
+
123
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
124
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
125
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
126
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
127
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
128
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
129
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,37 @@
1
+ require 'rubygems'
2
+ gem 'hoe', '>= 2.1.0'
3
+ require 'hoe'
4
+ require 'fileutils'
5
+
6
+ require './lib/looksee/version'
7
+
8
+ Hoe.plugin :newgem
9
+ Hoe.plugin :email # from seattlerb - configure via ~/.hoerc
10
+
11
+ $hoe = Hoe.spec 'looksee' do
12
+ self.developer 'George Ogata', 'george.ogata@gmail.com'
13
+ self.rubyforge_name = self.name # TODO this is default value
14
+ # self.extra_deps = [['activesupport','>= 2.0.2']]
15
+ self.extra_dev_deps = [
16
+ ['newgem', ">= #{::Newgem::VERSION}"],
17
+ ['rspec', '>= 1.2.7'],
18
+ ['mocha', '>= 0.9.5'],
19
+ ]
20
+ end
21
+
22
+ # Configure the clean and clobber tasks.
23
+ require 'rake/clean'
24
+ require 'rbconfig'
25
+ CLEAN.include('**/*.o')
26
+ CLOBBER.include("ext/looksee/looksee.#{Config::CONFIG['DLEXT']}")
27
+
28
+ require 'newgem/tasks' # loads /tasks/*.rake
29
+ Dir['tasks/**/*.rake'].each { |t| load t }
30
+
31
+ desc "Rebuild the gem from scratch."
32
+ task :regem => [:clobber, :gem]
33
+
34
+ # Force build before running specs.
35
+ Rake::Task['spec'].prerequisites << 'extconf:compile'
36
+
37
+ task :default => :spec
@@ -0,0 +1,6 @@
1
+ require 'mkmf'
2
+
3
+ $CPPFLAGS << " -DRUBY_VERSION=#{RUBY_VERSION.tr('.', '')}"
4
+ dir_config("looksee")
5
+
6
+ create_makefile("looksee")
@@ -0,0 +1,144 @@
1
+ #include "ruby.h"
2
+
3
+ #if RUBY_VERSION >= 190
4
+ # include "node-1.9.h"
5
+ # include "ruby/st.h"
6
+ #else
7
+ # include "node.h"
8
+ # include "st.h"
9
+ #endif
10
+
11
+ #if RUBY_VERSION < 187
12
+ # define RCLASS_IV_TBL(c) (RCLASS(c)->iv_tbl)
13
+ # define RCLASS_M_TBL(c) (RCLASS(c)->m_tbl)
14
+ # define RCLASS_SUPER(c) (RCLASS(c)->super)
15
+ #endif
16
+
17
+ /*
18
+ * Return the internal superclass of this class.
19
+ *
20
+ * This is either a Class or "IClass." IClasses represent Modules
21
+ * included in the ancestry, and should be treated as opaque objects
22
+ * in ruby space. Convert the IClass to a Module using #iclass_to_module
23
+ * before using it in ruby.
24
+ */
25
+ VALUE Looksee_internal_superclass(VALUE self, VALUE internal_class) {
26
+ VALUE super = RCLASS_SUPER(internal_class);
27
+ if (!super)
28
+ return Qnil;
29
+ return super;
30
+ }
31
+
32
+ /*
33
+ * Return the internal class of the given object.
34
+ *
35
+ * This is either the object's singleton class, if it exists, or the
36
+ * object's birth class.
37
+ */
38
+ VALUE Looksee_internal_class(VALUE self, VALUE object) {
39
+ return CLASS_OF(object);
40
+ }
41
+
42
+ /*
43
+ * Return the class or module that the given internal class
44
+ * represents.
45
+ *
46
+ * If a class is given, this is the class. If an iclass is given,
47
+ * this is the module it represents in the lookup chain.
48
+ */
49
+ VALUE Looksee_internal_class_to_module(VALUE self, VALUE internal_class) {
50
+ if (!SPECIAL_CONST_P(internal_class)) {
51
+ switch (BUILTIN_TYPE(internal_class)) {
52
+ case T_ICLASS:
53
+ return RBASIC(internal_class)->klass;
54
+ case T_CLASS:
55
+ return internal_class;
56
+ }
57
+ }
58
+ rb_raise(rb_eArgError, "not an internal class: %s", RSTRING_PTR(rb_inspect(internal_class)));
59
+ }
60
+
61
+ typedef struct add_method_if_matching_arg {
62
+ VALUE names;
63
+ int visibility;
64
+ } add_method_if_matching_arg_t;
65
+
66
+ #if RUBY_VERSION < 190
67
+ # define VISIBILITY(node) ((node)->nd_noex & NOEX_MASK)
68
+ #else
69
+ # define VISIBILITY(node) ((node)->nd_body->nd_noex & NOEX_MASK)
70
+ #endif
71
+
72
+ static int add_method_if_matching(ID method_name, NODE *body, add_method_if_matching_arg_t *arg) {
73
+ /* This entry is for the internal allocator function. */
74
+ if (method_name == ID_ALLOCATOR)
75
+ return ST_CONTINUE;
76
+
77
+ /* Module#undef_method sets body->nd_body to NULL. */
78
+ if (!body || !body->nd_body)
79
+ return ST_CONTINUE;
80
+
81
+ if (VISIBILITY(body) == arg->visibility)
82
+ rb_ary_push(arg->names, ID2SYM(method_name));
83
+ return ST_CONTINUE;
84
+ }
85
+
86
+ static VALUE internal_instance_methods(VALUE klass, long visibility) {
87
+ add_method_if_matching_arg_t arg;
88
+ arg.names = rb_ary_new();
89
+ arg.visibility = visibility;
90
+ st_foreach(RCLASS_M_TBL(klass), add_method_if_matching, (st_data_t)&arg);
91
+ return arg.names;
92
+ }
93
+
94
+ /*
95
+ * Return the list of public instance methods (as Symbols) of the
96
+ * given internal class.
97
+ */
98
+ VALUE Looksee_internal_public_instance_methods(VALUE self, VALUE klass) {
99
+ return internal_instance_methods(klass, NOEX_PUBLIC);
100
+ }
101
+
102
+ /*
103
+ * Return the list of protected instance methods (as Symbols) of the
104
+ * given internal class.
105
+ */
106
+ VALUE Looksee_internal_protected_instance_methods(VALUE self, VALUE klass) {
107
+ return internal_instance_methods(klass, NOEX_PROTECTED);
108
+ }
109
+
110
+ /*
111
+ * Return the list of private instance methods (as Symbols) of the
112
+ * given internal class.
113
+ */
114
+ VALUE Looksee_internal_private_instance_methods(VALUE self, VALUE klass) {
115
+ return internal_instance_methods(klass, NOEX_PRIVATE);
116
+ }
117
+
118
+ static int add_method_if_undefined(ID method_name, NODE *body, VALUE *names) {
119
+ /* Module#undef_method sets body->nd_body to NULL. */
120
+ if (body && !body->nd_body)
121
+ rb_ary_push(*names, ID2SYM(method_name));
122
+ return ST_CONTINUE;
123
+ }
124
+
125
+ /*
126
+ * Return the list of undefined instance methods (as Symbols) of the
127
+ * given internal class.
128
+ */
129
+ VALUE Looksee_internal_undefined_instance_methods(VALUE self, VALUE klass) {
130
+ VALUE names = rb_ary_new();
131
+ st_foreach(RCLASS_M_TBL(klass), add_method_if_undefined, (st_data_t)&names);
132
+ return names;
133
+ }
134
+
135
+ void Init_looksee(void) {
136
+ VALUE mLooksee = rb_define_module("Looksee");
137
+ rb_define_singleton_method(mLooksee, "internal_superclass", Looksee_internal_superclass, 1);
138
+ rb_define_singleton_method(mLooksee, "internal_class", Looksee_internal_class, 1);
139
+ rb_define_singleton_method(mLooksee, "internal_class_to_module", Looksee_internal_class_to_module, 1);
140
+ rb_define_singleton_method(mLooksee, "internal_public_instance_methods", Looksee_internal_public_instance_methods, 1);
141
+ rb_define_singleton_method(mLooksee, "internal_protected_instance_methods", Looksee_internal_protected_instance_methods, 1);
142
+ rb_define_singleton_method(mLooksee, "internal_private_instance_methods", Looksee_internal_private_instance_methods, 1);
143
+ rb_define_singleton_method(mLooksee, "internal_undefined_instance_methods", Looksee_internal_undefined_instance_methods, 1);
144
+ }
@@ -0,0 +1,35 @@
1
+ /* MRI 1.9 does not install node.h. This is the part we need. */
2
+
3
+ typedef struct RNode {
4
+ unsigned long flags;
5
+ char *nd_file;
6
+ union {
7
+ struct RNode *node;
8
+ ID id;
9
+ VALUE value;
10
+ VALUE (*cfunc)(ANYARGS);
11
+ ID *tbl;
12
+ } u1;
13
+ union {
14
+ struct RNode *node;
15
+ ID id;
16
+ long argc;
17
+ VALUE value;
18
+ } u2;
19
+ union {
20
+ struct RNode *node;
21
+ ID id;
22
+ long state;
23
+ struct global_entry *entry;
24
+ long cnt;
25
+ VALUE value;
26
+ } u3;
27
+ } NODE;
28
+
29
+ #define nd_body u2.node
30
+ #define nd_noex u3.id
31
+
32
+ #define NOEX_PUBLIC 0x00
33
+ #define NOEX_PRIVATE 0x02
34
+ #define NOEX_PROTECTED 0x04
35
+ #define NOEX_MASK 0x06
@@ -0,0 +1,63 @@
1
+ =begin
2
+
3
+ Include this to pollute the standard ruby modules with handy aliases.
4
+ Perfect for your .irbrc, or for punching into your program to work out
5
+ what that +flazbot+ variable can do.
6
+
7
+ =end
8
+
9
+ require 'looksee'
10
+
11
+ class Object
12
+ private # ---------------------------------------------------------
13
+
14
+ #
15
+ # Alias for Looksee.lookup_path.
16
+ #
17
+ # (Added by Looksee.)
18
+ #
19
+ def lp(*args)
20
+ Looksee.lookup_path(*args)
21
+ end
22
+
23
+ #
24
+ # Run Looksee.lookup_path on an instance of the given class.
25
+ #
26
+ # (Added by Looksee.)
27
+ #
28
+ def lpi(klass, *args)
29
+ Looksee.lookup_path(klass.allocate, *args)
30
+ end
31
+
32
+ #
33
+ # Run Looksee.colors to return the current color mappings.
34
+ #
35
+ # (Added by Looksee.)
36
+ #
37
+ def lc
38
+ Looksee.colors
39
+ end
40
+
41
+ public # ----------------------------------------------------------
42
+
43
+ #
44
+ # Call Looksee.lookup_path on this object.
45
+ #
46
+ # (Added by Looksee.)
47
+ #
48
+ def lookup_path(*args)
49
+ Looksee.lookup_path(self, *args)
50
+ end
51
+
52
+ #
53
+ # Dump the lookup path to standard output, and return self.
54
+ #
55
+ # Good for stuffing in a call chain.
56
+ #
57
+ # (Added by Looksee.)
58
+ #
59
+ def dump_lookup_path(*args)
60
+ p lookup_path(*args)
61
+ self
62
+ end
63
+ end
@@ -0,0 +1,3 @@
1
+ module Looksee
2
+ VERSION = '0.1.0'
3
+ end
@@ -0,0 +1,86 @@
1
+ module Looksee
2
+ module WirbleCompatibility
3
+ class << self
4
+ def wirble_loaded?
5
+ Object.const_defined?(:Wirble) &&
6
+ Wirble.is_a?(Module) &&
7
+ Wirble.respond_to?(:colorize)
8
+ end
9
+
10
+ def wirble_colorizing?
11
+ IRB::Irb.method_defined?(:non_color_output_value)
12
+ end
13
+
14
+ def hook_into_wirble_load
15
+ unless Object.const_defined?(:Wirble)
16
+ Object.const_set :Wirble, Module.new
17
+ end
18
+ Wirble.send :extend, WirbleLoadHook
19
+ end
20
+
21
+ def hook_into_wirble_colorize
22
+ class << Wirble
23
+ def colorize_with_looksee(*args)
24
+ # If this gets called twice, Wirble will fuck up the
25
+ # aliases. Disable colorizing first to reset them.
26
+ if WirbleCompatibility.hooked_into_irb_output_value?
27
+ Wirble::Colorize.disable
28
+ end
29
+ colorize_without_looksee(*args)
30
+ WirbleCompatibility.hook_into_irb_output_value
31
+ end
32
+
33
+ alias colorize_without_looksee colorize
34
+ alias colorize colorize_with_looksee
35
+ end
36
+ end
37
+
38
+ def hook_into_irb_output_value
39
+ IRB::Irb.class_eval do
40
+ def output_value_with_looksee
41
+ if @context.last_value.is_a?(Looksee::LookupPath)
42
+ non_color_output_value
43
+ else
44
+ output_value_without_looksee
45
+ end
46
+ end
47
+
48
+ alias output_value_without_looksee output_value
49
+ alias output_value output_value_with_looksee
50
+ end
51
+ end
52
+
53
+ def hooked_into_irb_output_value?
54
+ IRB::Irb.method_defined?(:output_value_with_looksee)
55
+ end
56
+
57
+ def init
58
+ #
59
+ # How wirble is used:
60
+ #
61
+ # * Wirble is required/loaded. Defines Wirble module, with methods like Wirble.colorize.
62
+ # * Wirble.init is called. Nothing interesting.
63
+ # * Wirble.colorize is called. Hooks into IRB::Irb.output_value via an alias.
64
+ #
65
+ if !wirble_loaded?
66
+ hook_into_wirble_load
67
+ elsif !wirble_colorizing?
68
+ hook_into_wirble_colorize
69
+ else
70
+ hook_into_irb_output_value
71
+ end
72
+ end
73
+ end
74
+
75
+ module WirbleLoadHook
76
+ def singleton_method_added(name)
77
+ if name == :colorize && !respond_to?(:colorize_with_looksee)
78
+ WirbleCompatibility.hook_into_wirble_colorize
79
+ end
80
+ super
81
+ end
82
+ end
83
+ end
84
+ end
85
+
86
+ Looksee::WirbleCompatibility.init