Project

General

Profile

Feature #13383

[PATCH] Module#source_location

Added by koba789 (Hidekazu Kobayashi) 7 months ago. Updated 5 months ago.

Status:
Open
Priority:
Normal
Assignee:
-
Target version:
-
[ruby-core:80458]

Description

Abstract

It can inspect where the module or class is defined.

Background

In debugging or development an application, I usually want to find out where the class definition of using library.
There is Method#source_location but I could not find Class easily.

Implementation

In Github: https://github.com/ruby/ruby/pull/1562

History

#1 [ruby-core:80465] Updated by nobu (Nobuyoshi Nakada) 7 months ago

Modules/classes can be opened again.
Your patch seems returning the last location instead of the first, is it intentional?

As for the implementation, it's not nice to keep iseq.
It would be better to save them in (hidden) instance variable(s).

#2 [ruby-core:80496] Updated by sorah (Sorah Fukumori) 7 months ago

it would be happier if we can get all of source locations where a class opened?

#3 [ruby-core:80498] Updated by sorah (Sorah Fukumori) 7 months ago

  • Tracker changed from Bug to Feature

Turning this into a feature ticket.

#4 [ruby-core:80499] Updated by shyouhei (Shyouhei Urabe) 7 months ago

In modern Ruby, prior to actually requiring a library, its gemspec tends to be loaded. From what I understand, people require foo/version.rb from foo.gemspec, and this is the first time when namespace foo is opened.

Is this info that useful?

#5 [ruby-core:80501] Updated by Eregon (Benoit Daloze) 7 months ago

shyouhei (Shyouhei Urabe) wrote:

In modern Ruby, prior to actually requiring a library, its gemspec tends to be loaded. From what I understand, people require foo/version.rb from foo.gemspec, and this is the first time when namespace foo is opened.

Is this info that useful?

I think that's only the case of the development gemspec in the repository.
If installed as a gem, the gemspec is a generated file from the metadata which does not require any other file.
Example:

# -*- encoding: utf-8 -*-
# stub: concurrent-ruby 1.0.2 ruby lib

Gem::Specification.new do |s|
  s.name = "concurrent-ruby"
  s.version = "1.0.2"

I agree it would be more useful to be able to collect all source locations where a Module was opened.

#6 [ruby-core:80508] Updated by shyouhei (Shyouhei Urabe) 7 months ago

Eregon (Benoit Daloze) wrote:

shyouhei (Shyouhei Urabe) wrote:

In modern Ruby, prior to actually requiring a library, its gemspec tends to be loaded. From what I understand, people require foo/version.rb from foo.gemspec, and this is the first time when namespace foo is opened.

Is this info that useful?

I think that's only the case of the development gemspec in the repository.
If installed as a gem, the gemspec is a generated file from the metadata which does not require any other file.

Great. I didn't know this. Thank you.

Example:

# -*- encoding: utf-8 -*-
# stub: concurrent-ruby 1.0.2 ruby lib

Gem::Specification.new do |s|
  s.name = "concurrent-ruby"
  s.version = "1.0.2"

I agree it would be more useful to be able to collect all source locations where a Module was opened.

Yes, I'm not against such feature.

#7 [ruby-core:80681] Updated by shevegen (Robert A. Heiler) 6 months ago

I am also for this if it is easily possible.

I remember many years ago in the ruby 1.8.x days, before pry,
I twiddled and played with the programming language Io.

I do not remember much about it, but one argument that it
said in its favour (aside from being small/lightweight)
was that it allowed introspection at run-time of pretty
much everything. (I do not remember if this was correct
or perhaps I may misremember.)

Since that, ruby got a lot more introspection support,
pry, also .source_location and being able to pull in
the method body and method comments (I think one of the
gems of pry does that).

I always found this awesome.

Anyway to come back to the suggestion by Hidekazu Kobayashi,
I agree. It would be nice to have full introspection of
everything in ruby at run-time. We got a lot more access
to all these various things these day, with the RubyVM and
objectspace showing memory even of a "namespace" like:

Like in my irb:

require 'objspace'; ObjectSpace.memsize_of([])     # => 20
require 'objspace'; ObjectSpace.memsize_of(Kernel) # => 2340
require 'objspace'; ObjectSpace.memsize_of(Object) # => 6484

I think that all of this is very cool. :)

#8 [ruby-core:81198] Updated by wanabe (_ wanabe) 5 months ago

sorah (Sorah Fukumori) wrote:

it would be happier if we can get all of source locations where a class opened?

I hope Module#source_locations, too. Like below:

# Just a PoC
class Module
  attr_reader :source_locations
end

TracePoint.new(:class) do |tp|
  tp.self.module_eval do
    @source_locations ||= []
    @source_locations << [tp.path, tp.lineno]
  end
end.enable

class Foo
end
class Foo
end

p Foo.source_locations #=> [["a.rb", 13], ["a.rb", 15]]

Also available in: Atom PDF