{"action":"created","issue":{"url":"https://api.github.com/repos/seattlerb/oedipus_lex/issues/8","labels_url":"https://api.github.com/repos/seattlerb/oedipus_lex/issues/8/labels{/name}","comments_url":"https://api.github.com/repos/seattlerb/oedipus_lex/issues/8/comments","events_url":"https://api.github.com/repos/seattlerb/oedipus_lex/issues/8/events","html_url":"https://github.com/seattlerb/oedipus_lex/pull/8","id":124524605,"number":8,"title":"Use `skip` and `match?` instead of `scan` and `check`","user":{"login":"presidentbeef","id":75613,"avatar_url":"https://avatars.githubusercontent.com/u/75613?v=3","gravatar_id":"","url":"https://api.github.com/users/presidentbeef","html_url":"https://github.com/presidentbeef","followers_url":"https://api.github.com/users/presidentbeef/followers","following_url":"https://api.github.com/users/presidentbeef/following{/other_user}","gists_url":"https://api.github.com/users/presidentbeef/gists{/gist_id}","starred_url":"https://api.github.com/users/presidentbeef/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/presidentbeef/subscriptions","organizations_url":"https://api.github.com/users/presidentbeef/orgs","repos_url":"https://api.github.com/users/presidentbeef/repos","events_url":"https://api.github.com/users/presidentbeef/events{/privacy}","received_events_url":"https://api.github.com/users/presidentbeef/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":{"login":"zenspider","id":9832,"avatar_url":"https://avatars.githubusercontent.com/u/9832?v=3","gravatar_id":"","url":"https://api.github.com/users/zenspider","html_url":"https://github.com/zenspider","followers_url":"https://api.github.com/users/zenspider/followers","following_url":"https://api.github.com/users/zenspider/following{/other_user}","gists_url":"https://api.github.com/users/zenspider/gists{/gist_id}","starred_url":"https://api.github.com/users/zenspider/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zenspider/subscriptions","organizations_url":"https://api.github.com/users/zenspider/orgs","repos_url":"https://api.github.com/users/zenspider/repos","events_url":"https://api.github.com/users/zenspider/events{/privacy}","received_events_url":"https://api.github.com/users/zenspider/received_events","type":"User","site_admin":false},"milestone":null,"comments":3,"created_at":"2016-01-01T01:16:52Z","updated_at":"2016-01-02T06:09:48Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/seattlerb/oedipus_lex/pulls/8","html_url":"https://github.com/seattlerb/oedipus_lex/pull/8","diff_url":"https://github.com/seattlerb/oedipus_lex/pull/8.diff","patch_url":"https://github.com/seattlerb/oedipus_lex/pull/8.patch"},"body":"`skip` and `match?` return the length of the match or `nil` instead of the matched string. They can be used anywhere the result of the match is not used, to avoid allocating unused strings.\r\n\r\nWhen scanning Redmine with Brakeman, I saw a 29% decrease in strings allocated by RubyParser. Most of these strings are pretty small, so the total allocated memory only decreased ~6%. Actual parsing times didn't seem to improve :sob:\r\n\r\nWhat do you think?"},"comment":{"url":"https://api.github.com/repos/seattlerb/oedipus_lex/issues/comments/168367399","html_url":"https://github.com/seattlerb/oedipus_lex/pull/8#issuecomment-168367399","issue_url":"https://api.github.com/repos/seattlerb/oedipus_lex/issues/8","id":168367399,"user":{"login":"zenspider","id":9832,"avatar_url":"https://avatars.githubusercontent.com/u/9832?v=3","gravatar_id":"","url":"https://api.github.com/users/zenspider","html_url":"https://github.com/zenspider","followers_url":"https://api.github.com/users/zenspider/followers","following_url":"https://api.github.com/users/zenspider/following{/other_user}","gists_url":"https://api.github.com/users/zenspider/gists{/gist_id}","starred_url":"https://api.github.com/users/zenspider/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zenspider/subscriptions","organizations_url":"https://api.github.com/users/zenspider/orgs","repos_url":"https://api.github.com/users/zenspider/repos","events_url":"https://api.github.com/users/zenspider/events{/privacy}","received_events_url":"https://api.github.com/users/zenspider/received_events","type":"User","site_admin":false},"created_at":"2016-01-02T06:09:47Z","updated_at":"2016-01-02T06:09:47Z","body":"Hrm... slightly more serious change:\r\n\r\n```ruby\r\n      uses_text = false\r\n\r\n      body =\r\n        case action\r\n        when nil, false then\r\n          \"  # do nothing\"\r\n        when /^\\{/ then\r\n          uses_text = action =~ /\\btext\\b/\r\n          \"  action #{action}\"\r\n        when /^:/, \"nil\" then\r\n          \"  [:state, #{action}]\"\r\n        else\r\n          uses_text = true\r\n          \"  #{action} text\"\r\n        end\r\n\r\n      cond = if uses_text then\r\n               \"text = ss.scan(#{regexp})\"\r\n             else\r\n               \"ss.skip(#{regexp})\"\r\n             end\r\n\r\n      cond = if exclusive or not start_state then\r\n               cond # no change\r\n             elsif start_state =~ /^:/ then\r\n               \"(state == #{start_state}) && (#{cond})\"\r\n             else\r\n               \"#{start_state} && (#{cond})\"\r\n             end\r\n\r\n      cond = \"when #{cond} then\"\r\n```"}}