Re: Getting basic data from Ruby itself?
Jörg W Mittag <[email protected]> Mon, 12 Aug 2019 01:08:40 +0200
| Newsgroups | gmane.comp.lang.ruby.general |
|---|---|
| Message-ID | <CAOEFna5MrVvOCzMp5JecqB_SM_meqtWiu+z9KFqW4z4BYa-p0g@mail.gmail.com> |
Leam Hall <[email protected]> wrote: > I'm building my study tools for the Ruby certification exam. Is there a > way to query Ruby itself for: > > Key words (def, begin, end, etc) > What those key words do No. Keywords aren't objects in Ruby, so there is no way to do anything with them. Ruby is an object-oriented language, in order to be able to do anything with something, that something needs to be an object. (Pretty much the only exception are variables; they aren't objects, but you can bind them and dereference them. That is however the only two things you can with them. You can't store a variable in a variable, you can't send a message to a variable, you can't return a variable.) There is a file in the YARV source code repository that briefly lists and documents keywords: https://github.com/ruby/ruby/blob/master/doc/keywords.rdoc . This is also rendered on https://ruby-doc.org/ : https://ruby-doc.org/core/doc/keywords_rdoc.html . Unfortunately, the inter-document links don't work, neither on GitHub nor on Ruby-Doc. You will have to manually follow them, e.g. by using the "Raw" view on GitHub: https://raw.githubusercontent.com/ruby/ruby/master/doc/keywords.rdoc There is also a file on https://ruby-doc.org/ that basically uses the trick of documenting the keywords as methods and then generating RDoc documentation from it: https://ruby-doc.org/docs/keywords/1.9/ . Note that both of these resources haven't been updated in a really long time, although I also cannot remember any new keywords being added since then. (However, `case` has learnt a new trick in Ruby 2.7, but that is still experimental and thus technically not "Ruby".) Also, obviously, neither of the two meets your criteria of "querying Ruby itself". Both are just documentation written by (fallible) humans. > The list of built-in modules and classes You can get somewhat close. You need to make sure that you don't load any non-core libraries, then just return Objectspace.each_object(Module).to_a E.g. by running ruby --disable-gems --disable-did_you_mean --disable-jit -e 'p ObjectSpace.each_object(Module).to_a' at a shell prompt. However, note that this will *not* return all core modules and classes but rather all modules and classes that exist without explicitly loading any additional code. Which is not the same thing. For example, when you run this on YARV, it will among others return the following modules and classes: ::RubyVM ::RubyVM::InstructionSequence ::RubyVM::AbstractSyntaxTree ::RubyVM::AbstractSyntaxTree::Node #<Class:RubyVM::AbstractSyntaxTree> ::RubyVM::MJIT #<Class:RubyVM::MJIT> These are all private internal implementation details of YARV and are *not* part of core Ruby. Note that we even get classes related to MJIT, although we *explicitly disabled* the JIT compiler. (Which is actually disabled by default, I only added that option for clarity.) If you were running the same on JRuby, you would get the top-level `::JRuby` module instead of `::RubyVM`, if you try it on TruffleRuby, you would get `::TruffleRuby`, if you try it on Rubinius, you would get `::Rubinius`. In fact, I haven't tried it, but on implementations like JRuby or Opal, you might even get the whole Java or ECMAScript class hierarchy as well. You will also note that there are some *singleton classes* in the list, but only a few. However, technically, *every object* has *always* a singleton class. (With very few exceptions such as `Integer`s, `true`, `false`, `nil`, `Symbol`s.) YARV will instantiate those lazily, which is why they don't show up in `ObjectSpace` (which is essentially the garbage-collected memory), but depending on your exact definition of "class" and "core Ruby", they are part of core Ruby. Note also that it isn't even obvious what "core Ruby" *is*. In fact, it isn't even obvious what "Ruby" is. We have * the ISO Ruby Language Specification (https://iso.org/standard/59579.html) * the book *The Ruby Programming Language* written by David Flanagan and Yukihiro "matz" Matsumoto * the book *Programming Ruby* * the Ruby Spec Suite (https://github.com/ruby/spec) * what YARV does * what matz considers to be "Ruby" in his head * what the community collectively considers to be "Ruby" Any single one of these, any combination of any of these, the intersection of some of these, the union of some of these, … they *all* could, by someone, somewhere, for some reason, reasonably be called "Ruby". > The standard library modules No, there is no way to get those. In order to make them available in Ruby, you need to load them first. Then, you can get them the same way as the core ones. Just save the core ones in an array and subtract, then you get only the newly loaded ones. But, this will also fail in some cases. E.g some standard libraries only monkey-patch existing core modules and classes. Obviously, you won't catch those, since the modules and classes will be the same before and after loading the library. Your best bet is to simply look at the documentation. But also here, we run into a question of definitions. For example, YARV is currently undergoing a process that is colloquially known as "the gemification of the standard library", where lots of what used to be standard libraries are split out into separate gems. Some of those gems that are split out, are then again turned into "bundled gems", i.e. gems that are installed together with YARv and don't need to be explicitly installed. Now, do you count bundled gems as part of the standard library or not? For additional complexity, many Ruby implementations have their own copy of the standard library. For even more complexity, some Ruby implementations share a common standard library derived from Rubinius's (which was actually gemified long before YARV started gemifying its standard library, and this entire standard library is, in fact, itself a gem: https://github.com/rubysl ). And to make matters really complex, while this standard library is used by several Ruby implementations, it is *not* used by YARV, which is the most widely-used one. I hope this didn't confuse you too much :-D Cheers, Jörg. Unsubscribe: <mailto:[email protected]?subject=unsubscribe> <http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk>