ConradIrwin / pry-debundle

Allows you to use gems not in your Gemfile from Pry.
MIT License
50 stars 9 forks source link

Add :when_started hook #4

Closed kyrylo closed 12 years ago

kyrylo commented 12 years ago

First of all, let's describe :when_started and :before_session hooks. The description is provided by John Mair:

Currently, "pry-debundle" has a problem with :before_session hook. The problem with it is a bit tricky and not really transparent. Let me explain that by showing a real-world example. I will take "pry-theme"[1] plugin as an example.

Let's imagine that we have a Rails project and we want to use Pry instead of IRB. We don't want to include all the Pry plugins that we use locally into our Gemfile, because they are specific for each taken separately programmer. Everyone uses his own plugins, so we don't want to clutter our Gemfile. Now then, we add only "pry-rails" and "pry-debundle" gems into our Gemfile:

gem "pry-rails", :group => :development gem "pry-debundle", :group => :development

Next, we do bundle install and launch our Rails console: rails c. Boom! Did you notice that too? The "pry-theme" doesn't work properly![2] But why is it so? The filthy worm hides in the boondocks of the Pry hooks. The problem is that currently "pry-debundle" uses :before_session hook. Every time you load a Rails console, Pry itself loads only those plugins that are defined in your Gemfile. Fathom this. Only the plugins from your Gemfile, if the file is present. Only "pry-rails" and "pry-debundle" gems in our particular case. Remember that we didn't add any of local Pry plugins to the Gemfile apart from these two? Yes, and "pry-theme" isn't loaded either by now.

What happens next is that "pry-debundle" comes into play. It reloads your Pry plugins without taking the Gemfile into account. Why? Well, that's what "pry-debundle" is about. It activates all your local Pry plugins, so there is no need to include them manually to your Gemfile. Looks about right, isn't it? OK, let's lean back, take a good cup of strong black tea (with a lemon), get our breath and try summarize what was said before (in chronological order):

1) Pry loads all Pry plugins from Gemfile, if any; 2) "pry-debundle" loads and activates other Pry plugins installed in the system.

But it still doesn't work properly. "pry-theme" is messed up for some reason. What the hell is going on? Good question, sir. Fortunately, I know the answer. And the answer is that "pry-debundle" lacks the proper hook to fire its own debundle! method. That's very simple: "pry-debundle" does not take into account hooks like :when_started defined in other Pry plugins. Such hooks are loaded by "pry-debundle", but never executed. It's an unreachable code. "pry-theme" uses :when_started hook of Pry to set a default colour theme, but it doesn't work nicely with "pry-debundle".

What wasn't transparent is the difference between :when_started and :before_session. As we can see, there is a big difference between them.

Fix the problem by adding :when_started hook to "pry-debundle". That would allow to execute :when_started hooks of other Pry plugins.

[1]: "pry-theme" is a Pry plugin, which colours Ruby code with help of ".prytheme" files. [2]: There is a relevant issue in "pry-theme" bug tracker. Check it out: https://github.com/kyrylo/pry-theme/issues/11

Signed-off-by: Kyrylo Silin kyrylosilin@gmail.com Acked-by: Conrad Irwin conrad.irwin@gmail.com

ConradIrwin commented 12 years ago

Thanks for this :). (In future, you might want to consider making your commit message a bit shorter; it should describe "what you did" and "why your fix works", the detailed discussion (and leisurely tea-drinking :p) can stay on the pull-request). Maybe something like this:

Handle :when_started hook

Some plugins, like pry-theme initialize themselves when the
`:when_started` hook is called. Now that pry-debundler can hook in to
`:when_started` those gems will initialize properly if they are required
from outside the Gemfile in `Pry.debundle!`.

Previously these gems were not initialized because pry-debundler would
wait until `:before_session` before calling `Pry.debundle!` and
`:before_session` always happens after `:when_started`.

Signed-off-by: Kyrylo Silin <kyrylosilin@gmail.com>

(also, no Acked-By: I didn't review your patch yet :p).

kyrylo commented 12 years ago

Ah, thanks! :)