Module IHelp
In: lib/ihelp.rb
RiDriver IHelpDriver Renderer lib/ihelp.rb IHelp Module: IHelp

Ri bindings for interactive use from within Ruby. Does a bit of second-guessing (Instance method? Class method? Try both unless explicitly defined. Not found in this class? Try the ancestor classes.)

Goal is that help is given for all methods that have help.

Examples:

  require 'ihelp'

  a = "string"
  a.help
  a.help :reverse
  a.help :map
  String.help
  String.help :new
  String.help :reverse
  String.help :map
  String.instance_help :reverse
  String.instance_help :new # => No help found.
  a.help :new
  help "String#reverse"
  help "String.reverse"
  a.method(:reverse).help # gets help for Method
  help "Hash#map"

Custom help renderers:

The help-method calls IHelp::Renderer’s method defined by IHelp.renderer with the RI info object. You can print help out the way you want by defining your own renderer method in IHelp::Renderer and setting IHelp.renderer to the name of the method.

Example:

  require 'ihelp'

  class IHelp::Renderer
    def print_name(info)
      puts info.full_name
    end
  end

  IHelp.renderer = :print_name

  [1,2,3].help:reject
  # Array#reject
  # => nil

The current renderers are:

  ri -- the default renderer
  html -- creates a HTML document for the help and opens it
          with the program named in IHelp::WWW_BROWSER
  rubydoc_org -- opens the corresponding www.ruby-doc.org class
                 documentation page with the program named in
                 IHelp::WWW_BROWSER
  rubytoruby_src -- uses RubyToRuby to print the source for the method
                    (highly experimental)

License: Ruby’s

Author: Ilmari Heikkinen <kig misfiring net>

Methods

Classes and Modules

Class IHelp::IHelpDriver
Class IHelp::Renderer

Constants

HELP_VERSION = "0.3.1"
WWW_BROWSER = 'firefox'
RI_ARGS = []
RI_ARGS = ENV["RI"].split.concat(ARGV)

Attributes

renderer  [RW] 

Public Class methods

Return RI::ClassDescription / RI::MethodDescription for klass or its method meth, or its instance method meth if instance == true.

[Source]

     # File lib/ihelp.rb, line 230
230:     def generate_help_description(klass, meth=nil, instance=nil)
231:       meth_str = nil
232:       double_colon = false
233:       if meth
234:         meth_str = meth.to_s
235:         if /::|\.|#/ === meth_str # called with e.g."Array#str","String.new"
236:           meth_str, klass_name, instance_help, double_colon = 
237:             get_help_klass_info_for_name(meth_str)
238:             klass_ancs = find_ancestors(klass_name, instance)  
239:         else
240:           klass_name, klass_ancs, instance_help = 
241:             get_help_klass_info(klass, instance)
242:         end
243:       else
244:         klass_name, klass_ancs, instance_help = 
245:           get_help_klass_info(klass, instance)
246:       end
247:       info = get_help_info(meth_str, klass_name, klass_ancs, instance_help,
248:                            instance)
249:       # Retry with method as class if double_colon-splitted and no info
250:       if info.nil? and double_colon 
251:         klass_name = [klass_name, meth_str].join("::")
252:         meth_str = nil
253:         klass_ancs = find_ancestors(klass_name, instance)
254:         info = get_help_info(
255:                  meth_str, klass_name, klass_ancs, instance_help, instance)
256:       end
257:       info
258:     end

Render the RI info object a renderer method in IHelp::Renderer. The name of the renderer method to use is returned by IHelp.renderer, and can be set with IHelp.renderer=.

[Source]

     # File lib/ihelp.rb, line 219
219:     def render(info)
220:       IHelp::Renderer.new.send(renderer, info)
221:     end

[Source]

     # File lib/ihelp.rb, line 223
223:     def ri_driver
224:       @ri_driver ||= IHelpDriver.new(RI_ARGS)
225:     end

Private Class methods

Find ancestors for klass_name (works if the class has been loaded)

[Source]

     # File lib/ihelp.rb, line 302
302:     def find_ancestors(klass_name, instance)
303:       similarily_named_class = nil
304:       ObjectSpace.each_object(Class){|k| 
305:         similarily_named_class = k if k.name == klass_name
306:         break if similarily_named_class
307:       }
308:       if similarily_named_class
309:         klass_ancs = similarily_named_class.ancestors
310:         klass_ancs += similarily_named_class.class.ancestors unless instance
311:       else
312:         klass_ancs = []
313:       end
314:       klass_ancs
315:     end

[Source]

     # File lib/ihelp.rb, line 317
317:     def get_help_info(meth_str, klass_name, klass_ancs, instance_help, instance)
318:       info = get_help_info_str(meth_str, klass_name, klass_ancs, instance_help)
319:       # If instance is undefined, try both the class methods and instance
320:       # methods.
321:       if info.nil? and instance.nil?
322:         info = get_help_info_str(
323:                  meth_str, klass_name, klass_ancs, (not instance_help))
324:       end
325:       info
326:     end

[Source]

     # File lib/ihelp.rb, line 328
328:     def get_help_info_str(meth_str, klass_name, klass_ancs, instance)
329:         info_str = ri_driver.get_info_str(klass_name, meth_str, instance)
330:         if not info_str
331:           # Walk through class hierarchy to find an inherited method
332:           ancest = klass_ancs.find{|anc|
333:             info_str = ri_driver.get_info_str(anc.name, meth_str, instance)
334:           }
335:           # Avoid returning Object in case of no help.
336:           if ancest == Object and meth_str.nil? and klass_name != Object.name
337:             info_str = nil 
338:           end
339:         end
340:         info_str
341:     end

[Source]

     # File lib/ihelp.rb, line 261
261:     def get_help_klass_info(klass,instance)
262:         if klass.is_a? Class or klass.is_a? Module
263:           klass_ancs = klass.ancestors + klass.class.ancestors
264:           klass_ancs -= [klass, klass.class]
265:           instance = false if instance.nil?
266:         # If we are an instance, set klass to our class
267:         #
268:         else
269:           klass = klass.class
270:           klass_ancs = klass.ancestors - [klass]
271:           instance = true if instance.nil?
272:         end
273:         klass_name = klass.name
274:         [klass_name, klass_ancs, instance]
275:     end

[Source]

     # File lib/ihelp.rb, line 277
277:     def get_help_klass_info_for_name(meth_str)
278:       double_colon = false
279:       # Maybe we are being called with something like "Array#slice"
280:       if /#/ === meth_str
281:         klass_name, meth_str = meth_str.split(/#/, 2)
282:         instance = true
283:   
284:       # Or maybe the requested item is "Ri::RiDriver.new"
285:       elsif /\./ === meth_str
286:         klass_name, meth_str = meth_str.reverse.split(/\./, 2).
287:                                         reverse.map{|i| i.reverse}
288:         instance = false
289:   
290:       # And the problematic case of "Test::Unit" (is Unit a class name or
291:       # a method name? Why does Ri even care?)
292:       else
293:         klass_name, meth_str = meth_str.reverse.split(/::/, 2).
294:                                         reverse.map{|i| i.reverse}
295:         double_colon = true
296:         instance = false
297:       end
298:       [meth_str, klass_name, instance, double_colon]
299:     end

Public Instance methods

Print out help for self.

  If method_name is given, prints help for that method.
  If instance is true, tries to find help only for the instance method.
  If instance is false, tries to find help for the object's method only.
  If instance is nil, checks object's method first, then instance method.

Uses help_description(method_name, instance).

[Source]

     # File lib/ihelp.rb, line 154
154:   def help(method_name=nil, instance=nil)
155:     info = help_description(method_name, instance)
156:     if not info
157:       puts "No help found."
158:       return
159:     end 
160:     IHelp.render(info)
161:   end

Return RI::ClassDescription / RI::MethodDescription for self or its method meth, or its instance method meth if instance == true.

[Source]

     # File lib/ihelp.rb, line 199
199:   def help_description(method_name=nil, instance=nil)
200:     IHelp.generate_help_description(self, method_name, instance)
201:   end

Returns help string as a HTML REXML::Document with a DIV element as the root.

  If method_name is given, prints help for that method.
  If instance is true, tries to find help only for the instance method.
  If instance is false, tries to find help for the object's method only.
  If instance is nil, checks object's method first, then instance method.
  Returns nil if there is no help to be found.

[Source]

     # File lib/ihelp.rb, line 191
191:   def help_html(method_name=nil, instance=nil)
192:     info = help_description(method_name, instance)
193:     info.to_html if info
194:   end

Returns help string in YAML for self.

  If method_name is given, prints help for that method.
  If instance is true, tries to find help only for the instance method.
  If instance is false, tries to find help for the object's method only.
  If instance is nil, checks object's method first, then instance method.
  Returns nil if there is no help to be found.

[Source]

     # File lib/ihelp.rb, line 178
178:   def help_yaml(method_name=nil, instance=nil)
179:     info = help_description(method_name, instance)
180:     info.to_yaml if info
181:   end

Print out help for instance method method_name. If no method_name given, behaves like help.

[Source]

     # File lib/ihelp.rb, line 166
166:   def instance_help(method_name = nil)
167:     help(method_name, true)
168:   end

[Validate]