{"action":"closed","number":99,"pull_request":{"url":"https://api.github.com/repos/rails/web-console/pulls/99","id":28011945,"html_url":"https://github.com/rails/web-console/pull/99","diff_url":"https://github.com/rails/web-console/pull/99.diff","patch_url":"https://github.com/rails/web-console/pull/99.patch","issue_url":"https://api.github.com/repos/rails/web-console/issues/99","number":99,"state":"closed","locked":false,"title":"Improve JRuby and Rubinius integrations","user":{"login":"gsamokovarov","id":604618,"avatar_url":"https://avatars.githubusercontent.com/u/604618?v=3","gravatar_id":"","url":"https://api.github.com/users/gsamokovarov","html_url":"https://github.com/gsamokovarov","followers_url":"https://api.github.com/users/gsamokovarov/followers","following_url":"https://api.github.com/users/gsamokovarov/following{/other_user}","gists_url":"https://api.github.com/users/gsamokovarov/gists{/gist_id}","starred_url":"https://api.github.com/users/gsamokovarov/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gsamokovarov/subscriptions","organizations_url":"https://api.github.com/users/gsamokovarov/orgs","repos_url":"https://api.github.com/users/gsamokovarov/repos","events_url":"https://api.github.com/users/gsamokovarov/events{/privacy}","received_events_url":"https://api.github.com/users/gsamokovarov/received_events","type":"User","site_admin":false},"body":"Both JRuby and Rubinius had poor support in 2.0 stable. The approach\r\nthat works for CRuby isn't applicable for them. Therefore, I took them\r\napart and dug deeper to provide better support.\r\n\r\n## JRuby\r\n\r\nJRuby's support halted when custom errors forgot to call super in their\r\ninitialize methods. A more reliable hook for the raise event is\r\navailable as a `org.jruby.runtime.EventHook` subclass. The easiest way I\r\nfound to interact with those in plain JRuby was `Kernel#set_trace_func`,\r\nwhich is internally implements an `EventHook`.\r\n\r\nAnother quirk with JRuby is that we can't reliably evaluate code in\r\nparents binding, because of the JIT. We can, in fact, get them even in\r\ncompiled mode, however evaluating code in them may not work, if the\r\nunderlying code is optimized. `binding_of_caller` disallows it for that\r\nparticular reason.\r\n\r\nTo hint the users, I used to display a require-time message on user's\r\nterminal to help them run JRuby in interpreted mode. However, this\r\nmessage triggers for every Rails related commands, like rake tasks. I\r\nbelieve that a lot of the folks that use JRuby don't run it in interpreted\r\nmode, and for them, this message will pop up all the time.\r\n\r\nTo provide what I think is a better UI, I moved the message to the\r\nconsole web view. If you run with regular JRuby, you will get the\r\nconsole on a page, however, every command you type will tell you\r\nhow to run interpreted mode right there.\r\n\r\n## Rubinius\r\n\r\nRubinius' had the same problem as JRuby. Custom exceptions that\r\nforgot to call super in initialize weren't caught. It also had a pretty\r\nfragile implementation to figure out which frame was the first one\r\noutside of kernel/delta/kernel.rb's pure Ruby implementation of\r\n`Kernel#raise`.\r\n\r\nAnother bug it suffered from was that binding_of_caller\r\nisn't able to construct bindings for specific C extensions, like event\r\nmachine and blew out with nil error when you tried to run a rails\r\nserver, on a port that isn't open, for example.\r\n\r\nRubinius gives us access to ::Rubinius::VM.backtrace which returns\r\ninternal objects we can use to build the current bindings. This helped\r\nme more reliably filter out the bindings coming from `Kernel#raise` and\r\nget rid of the nil errors.\r\n\r\nThe drawback of the current approach is that it won't catch some special\r\nRubinius specific errors. However, Rubinius doesn't support `set_trace_func`\r\nand this is the best approach I know of for now.","created_at":"2015-01-26T08:40:26Z","updated_at":"2015-02-21T17:03:16Z","closed_at":"2015-02-21T17:03:16Z","merged_at":"2015-02-21T17:03:16Z","merge_commit_sha":"d52d59148565dc2371c31384c9619c1ec7469126","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/rails/web-console/pulls/99/commits","review_comments_url":"https://api.github.com/repos/rails/web-console/pulls/99/comments","review_comment_url":"https://api.github.com/repos/rails/web-console/pulls/comments/{number}","comments_url":"https://api.github.com/repos/rails/web-console/issues/99/comments","statuses_url":"https://api.github.com/repos/rails/web-console/statuses/86b3b0b5695f7f8c14143cabe81f3dc601655f52","head":{"label":"gsamokovarov:integrations","ref":"integrations","sha":"86b3b0b5695f7f8c14143cabe81f3dc601655f52","user":{"login":"gsamokovarov","id":604618,"avatar_url":"https://avatars.githubusercontent.com/u/604618?v=3","gravatar_id":"","url":"https://api.github.com/users/gsamokovarov","html_url":"https://github.com/gsamokovarov","followers_url":"https://api.github.com/users/gsamokovarov/followers","following_url":"https://api.github.com/users/gsamokovarov/following{/other_user}","gists_url":"https://api.github.com/users/gsamokovarov/gists{/gist_id}","starred_url":"https://api.github.com/users/gsamokovarov/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gsamokovarov/subscriptions","organizations_url":"https://api.github.com/users/gsamokovarov/orgs","repos_url":"https://api.github.com/users/gsamokovarov/repos","events_url":"https://api.github.com/users/gsamokovarov/events{/privacy}","received_events_url":"https://api.github.com/users/gsamokovarov/received_events","type":"User","site_admin":false},"repo":{"id":10462492,"name":"web-console","full_name":"gsamokovarov/web-console","owner":{"login":"gsamokovarov","id":604618,"avatar_url":"https://avatars.githubusercontent.com/u/604618?v=3","gravatar_id":"","url":"https://api.github.com/users/gsamokovarov","html_url":"https://github.com/gsamokovarov","followers_url":"https://api.github.com/users/gsamokovarov/followers","following_url":"https://api.github.com/users/gsamokovarov/following{/other_user}","gists_url":"https://api.github.com/users/gsamokovarov/gists{/gist_id}","starred_url":"https://api.github.com/users/gsamokovarov/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gsamokovarov/subscriptions","organizations_url":"https://api.github.com/users/gsamokovarov/orgs","repos_url":"https://api.github.com/users/gsamokovarov/repos","events_url":"https://api.github.com/users/gsamokovarov/events{/privacy}","received_events_url":"https://api.github.com/users/gsamokovarov/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/gsamokovarov/web-console","description":"MOVED TO https://github.com/rails/web-console","fork":false,"url":"https://api.github.com/repos/gsamokovarov/web-console","forks_url":"https://api.github.com/repos/gsamokovarov/web-console/forks","keys_url":"https://api.github.com/repos/gsamokovarov/web-console/keys{/key_id}","collaborators_url":"https://api.github.com/repos/gsamokovarov/web-console/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/gsamokovarov/web-console/teams","hooks_url":"https://api.github.com/repos/gsamokovarov/web-console/hooks","issue_events_url":"https://api.github.com/repos/gsamokovarov/web-console/issues/events{/number}","events_url":"https://api.github.com/repos/gsamokovarov/web-console/events","assignees_url":"https://api.github.com/repos/gsamokovarov/web-console/assignees{/user}","branches_url":"https://api.github.com/repos/gsamokovarov/web-console/branches{/branch}","tags_url":"https://api.github.com/repos/gsamokovarov/web-console/tags","blobs_url":"https://api.github.com/repos/gsamokovarov/web-console/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/gsamokovarov/web-console/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/gsamokovarov/web-console/git/refs{/sha}","trees_url":"https://api.github.com/repos/gsamokovarov/web-console/git/trees{/sha}","statuses_url":"https://api.github.com/repos/gsamokovarov/web-console/statuses/{sha}","languages_url":"https://api.github.com/repos/gsamokovarov/web-console/languages","stargazers_url":"https://api.github.com/repos/gsamokovarov/web-console/stargazers","contributors_url":"https://api.github.com/repos/gsamokovarov/web-console/contributors","subscribers_url":"https://api.github.com/repos/gsamokovarov/web-console/subscribers","subscription_url":"https://api.github.com/repos/gsamokovarov/web-console/subscription","commits_url":"https://api.github.com/repos/gsamokovarov/web-console/commits{/sha}","git_commits_url":"https://api.github.com/repos/gsamokovarov/web-console/git/commits{/sha}","comments_url":"https://api.github.com/repos/gsamokovarov/web-console/comments{/number}","issue_comment_url":"https://api.github.com/repos/gsamokovarov/web-console/issues/comments/{number}","contents_url":"https://api.github.com/repos/gsamokovarov/web-console/contents/{+path}","compare_url":"https://api.github.com/repos/gsamokovarov/web-console/compare/{base}...{head}","merges_url":"https://api.github.com/repos/gsamokovarov/web-console/merges","archive_url":"https://api.github.com/repos/gsamokovarov/web-console/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/gsamokovarov/web-console/downloads","issues_url":"https://api.github.com/repos/gsamokovarov/web-console/issues{/number}","pulls_url":"https://api.github.com/repos/gsamokovarov/web-console/pulls{/number}","milestones_url":"https://api.github.com/repos/gsamokovarov/web-console/milestones{/number}","notifications_url":"https://api.github.com/repos/gsamokovarov/web-console/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/gsamokovarov/web-console/labels{/name}","releases_url":"https://api.github.com/repos/gsamokovarov/web-console/releases{/id}","created_at":"2013-06-03T19:18:56Z","updated_at":"2015-01-18T11:06:02Z","pushed_at":"2015-02-21T16:55:55Z","git_url":"git://github.com/gsamokovarov/web-console.git","ssh_url":"git@github.com:gsamokovarov/web-console.git","clone_url":"https://github.com/gsamokovarov/web-console.git","svn_url":"https://github.com/gsamokovarov/web-console","homepage":"","size":1829,"stargazers_count":23,"watchers_count":23,"language":"Ruby","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":60,"mirror_url":null,"open_issues_count":0,"forks":60,"open_issues":0,"watchers":23,"default_branch":"master"}},"base":{"label":"rails:master","ref":"master","sha":"ed7b20bfd9174bee77f1835f0a8c8af4c6088f9a","user":{"login":"rails","id":4223,"avatar_url":"https://avatars.githubusercontent.com/u/4223?v=3","gravatar_id":"","url":"https://api.github.com/users/rails","html_url":"https://github.com/rails","followers_url":"https://api.github.com/users/rails/followers","following_url":"https://api.github.com/users/rails/following{/other_user}","gists_url":"https://api.github.com/users/rails/gists{/gist_id}","starred_url":"https://api.github.com/users/rails/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rails/subscriptions","organizations_url":"https://api.github.com/users/rails/orgs","repos_url":"https://api.github.com/users/rails/repos","events_url":"https://api.github.com/users/rails/events{/privacy}","received_events_url":"https://api.github.com/users/rails/received_events","type":"Organization","site_admin":false},"repo":{"id":12496351,"name":"web-console","full_name":"rails/web-console","owner":{"login":"rails","id":4223,"avatar_url":"https://avatars.githubusercontent.com/u/4223?v=3","gravatar_id":"","url":"https://api.github.com/users/rails","html_url":"https://github.com/rails","followers_url":"https://api.github.com/users/rails/followers","following_url":"https://api.github.com/users/rails/following{/other_user}","gists_url":"https://api.github.com/users/rails/gists{/gist_id}","starred_url":"https://api.github.com/users/rails/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rails/subscriptions","organizations_url":"https://api.github.com/users/rails/orgs","repos_url":"https://api.github.com/users/rails/repos","events_url":"https://api.github.com/users/rails/events{/privacy}","received_events_url":"https://api.github.com/users/rails/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/rails/web-console","description":"Rails Console on the Browser.","fork":true,"url":"https://api.github.com/repos/rails/web-console","forks_url":"https://api.github.com/repos/rails/web-console/forks","keys_url":"https://api.github.com/repos/rails/web-console/keys{/key_id}","collaborators_url":"https://api.github.com/repos/rails/web-console/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/rails/web-console/teams","hooks_url":"https://api.github.com/repos/rails/web-console/hooks","issue_events_url":"https://api.github.com/repos/rails/web-console/issues/events{/number}","events_url":"https://api.github.com/repos/rails/web-console/events","assignees_url":"https://api.github.com/repos/rails/web-console/assignees{/user}","branches_url":"https://api.github.com/repos/rails/web-console/branches{/branch}","tags_url":"https://api.github.com/repos/rails/web-console/tags","blobs_url":"https://api.github.com/repos/rails/web-console/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/rails/web-console/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/rails/web-console/git/refs{/sha}","trees_url":"https://api.github.com/repos/rails/web-console/git/trees{/sha}","statuses_url":"https://api.github.com/repos/rails/web-console/statuses/{sha}","languages_url":"https://api.github.com/repos/rails/web-console/languages","stargazers_url":"https://api.github.com/repos/rails/web-console/stargazers","contributors_url":"https://api.github.com/repos/rails/web-console/contributors","subscribers_url":"https://api.github.com/repos/rails/web-console/subscribers","subscription_url":"https://api.github.com/repos/rails/web-console/subscription","commits_url":"https://api.github.com/repos/rails/web-console/commits{/sha}","git_commits_url":"https://api.github.com/repos/rails/web-console/git/commits{/sha}","comments_url":"https://api.github.com/repos/rails/web-console/comments{/number}","issue_comment_url":"https://api.github.com/repos/rails/web-console/issues/comments/{number}","contents_url":"https://api.github.com/repos/rails/web-console/contents/{+path}","compare_url":"https://api.github.com/repos/rails/web-console/compare/{base}...{head}","merges_url":"https://api.github.com/repos/rails/web-console/merges","archive_url":"https://api.github.com/repos/rails/web-console/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/rails/web-console/downloads","issues_url":"https://api.github.com/repos/rails/web-console/issues{/number}","pulls_url":"https://api.github.com/repos/rails/web-console/pulls{/number}","milestones_url":"https://api.github.com/repos/rails/web-console/milestones{/number}","notifications_url":"https://api.github.com/repos/rails/web-console/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/rails/web-console/labels{/name}","releases_url":"https://api.github.com/repos/rails/web-console/releases{/id}","created_at":"2013-08-30T21:57:37Z","updated_at":"2015-02-21T15:31:49Z","pushed_at":"2015-02-21T17:03:16Z","git_url":"git://github.com/rails/web-console.git","ssh_url":"git@github.com:rails/web-console.git","clone_url":"https://github.com/rails/web-console.git","svn_url":"https://github.com/rails/web-console","homepage":"","size":1864,"stargazers_count":736,"watchers_count":736,"language":"Ruby","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":56,"mirror_url":null,"open_issues_count":10,"forks":56,"open_issues":10,"watchers":736,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/rails/web-console/pulls/99"},"html":{"href":"https://github.com/rails/web-console/pull/99"},"issue":{"href":"https://api.github.com/repos/rails/web-console/issues/99"},"comments":{"href":"https://api.github.com/repos/rails/web-console/issues/99/comments"},"review_comments":{"href":"https://api.github.com/repos/rails/web-console/pulls/99/comments"},"review_comment":{"href":"https://api.github.com/repos/rails/web-console/pulls/comments/{number}"},"commits":{"href":"https://api.github.com/repos/rails/web-console/pulls/99/commits"},"statuses":{"href":"https://api.github.com/repos/rails/web-console/statuses/86b3b0b5695f7f8c14143cabe81f3dc601655f52"}},"merged":true,"mergeable":null,"mergeable_state":"unknown","merged_by":{"login":"gsamokovarov","id":604618,"avatar_url":"https://avatars.githubusercontent.com/u/604618?v=3","gravatar_id":"","url":"https://api.github.com/users/gsamokovarov","html_url":"https://github.com/gsamokovarov","followers_url":"https://api.github.com/users/gsamokovarov/followers","following_url":"https://api.github.com/users/gsamokovarov/following{/other_user}","gists_url":"https://api.github.com/users/gsamokovarov/gists{/gist_id}","starred_url":"https://api.github.com/users/gsamokovarov/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gsamokovarov/subscriptions","organizations_url":"https://api.github.com/users/gsamokovarov/orgs","repos_url":"https://api.github.com/users/gsamokovarov/repos","events_url":"https://api.github.com/users/gsamokovarov/events{/privacy}","received_events_url":"https://api.github.com/users/gsamokovarov/received_events","type":"User","site_admin":false},"comments":0,"review_comments":0,"commits":6,"additions":355,"deletions":148,"changed_files":20}}