{"action":"created","issue":{"url":"https://api.github.com/repos/soveran/syro/issues/29","repository_url":"https://api.github.com/repos/soveran/syro","labels_url":"https://api.github.com/repos/soveran/syro/issues/29/labels{/name}","comments_url":"https://api.github.com/repos/soveran/syro/issues/29/comments","events_url":"https://api.github.com/repos/soveran/syro/issues/29/events","html_url":"https://github.com/soveran/syro/issues/29","id":376872133,"node_id":"MDU6SXNzdWUzNzY4NzIxMzM=","number":29,"title":"RFC: Composable Routes","user":{"login":"evanleck","id":21947,"node_id":"MDQ6VXNlcjIxOTQ3","avatar_url":"https://avatars3.githubusercontent.com/u/21947?v=4","gravatar_id":"","url":"https://api.github.com/users/evanleck","html_url":"https://github.com/evanleck","followers_url":"https://api.github.com/users/evanleck/followers","following_url":"https://api.github.com/users/evanleck/following{/other_user}","gists_url":"https://api.github.com/users/evanleck/gists{/gist_id}","starred_url":"https://api.github.com/users/evanleck/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/evanleck/subscriptions","organizations_url":"https://api.github.com/users/evanleck/orgs","repos_url":"https://api.github.com/users/evanleck/repos","events_url":"https://api.github.com/users/evanleck/events{/privacy}","received_events_url":"https://api.github.com/users/evanleck/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":1,"created_at":"2018-11-02T16:04:39Z","updated_at":"2018-11-02T17:35:58Z","closed_at":null,"author_association":"NONE","body":"Hello!\r\n\r\nI'm working on a project that requires what I'm calling \"route partials\" that can be shared across Syro instances or route locations within a single instance. Looking through the code I don't see a good way to do that that doesn't involve actually _capturing_ the route execution like with `run`, so I came up with a solution that works for my needs but thought I'd share the idea here to see if you think it's worth including in Syro itself.\r\n\r\nLet's say we have a Syro instance like this that we'd like to include as a kind of partial in other Syro instances:\r\n\r\n```ruby\r\nHelp = Syro.new do\r\n  on('help') do\r\n    res.text \"Help!\"\r\n  end\r\nend\r\n```\r\n\r\nAnd using the main Syro application below, we'd like the `Help` route to run at \"/foo/help\" and \"/bar/help\".\r\n\r\n```ruby\r\nMain = Syro.new do\r\n  on('foo') do\r\n    res.text \"Foo!\"\r\n  end\r\n\r\n  on('bar') do\r\n    res.text \"Bar!\"\r\n  end\r\nend\r\n```\r\n\r\nThe solution that I came up with was to expose the captured code block via an accessor and add a method to the main deck like so that evals the code (just like `#call`) in place:\r\n\r\n```ruby\r\nclass Syro\r\n  class Deck\r\n    module API\r\n      def with(route)\r\n        instance_eval(&route.code)\r\n      end\r\n    end\r\n  end\r\n\r\n  attr_accessor :code\r\nend\r\n```\r\n\r\nNow, to run `Help` at both \"/foo/help\" and \"/bar/help\" we'd do this:\r\n\r\n```\r\nMain = Syro.new do\r\n  on('foo') do\r\n    with(Help)\r\n\r\n    res.text \"Foo!\"\r\n  end\r\n\r\n  on('bar') do\r\n    with(Help)\r\n\r\n    res.text \"Bar!\"\r\n  end\r\nend\r\n```\r\n\r\nThe big difference when compared with `run` is that the route _could_ get captured by the Syro instance handed to `with` but doesn't have to. It may not match and would then continue execution in the \"foo\" or \"bar\" block, respectively. We also don't have to duplicate the capturing logic e.g. `on('help') do` in both places since that's contained in `Help`.\r\n\r\nThe biggest problem that I see and that I don't have a good solution for is the fact that `Help`'s deck is completely ignored when run via `with` because we're evaluating `Help`'s block of code in the context of the class calling `with`. Another version of this could use a `Proc` instance instead of an instance of Syro and would do basically the same thing.\r\n\r\nAnyway, thanks for reading! If you think this is worth pursuing I'd be happy to create a pull request or if you'd like more examples or a better explanation of anything please let me know."},"comment":{"url":"https://api.github.com/repos/soveran/syro/issues/comments/435454592","html_url":"https://github.com/soveran/syro/issues/29#issuecomment-435454592","issue_url":"https://api.github.com/repos/soveran/syro/issues/29","id":435454592,"node_id":"MDEyOklzc3VlQ29tbWVudDQzNTQ1NDU5Mg==","user":{"login":"soveran","id":951,"node_id":"MDQ6VXNlcjk1MQ==","avatar_url":"https://avatars0.githubusercontent.com/u/951?v=4","gravatar_id":"","url":"https://api.github.com/users/soveran","html_url":"https://github.com/soveran","followers_url":"https://api.github.com/users/soveran/followers","following_url":"https://api.github.com/users/soveran/following{/other_user}","gists_url":"https://api.github.com/users/soveran/gists{/gist_id}","starred_url":"https://api.github.com/users/soveran/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/soveran/subscriptions","organizations_url":"https://api.github.com/users/soveran/orgs","repos_url":"https://api.github.com/users/soveran/repos","events_url":"https://api.github.com/users/soveran/events{/privacy}","received_events_url":"https://api.github.com/users/soveran/received_events","type":"User","site_admin":false},"created_at":"2018-11-02T17:35:58Z","updated_at":"2018-11-02T17:35:58Z","author_association":"OWNER","body":"@evanleck If I understand correctly, it's something like what I described here: https://github.com/soveran/cuba#embedding-routes-from-other-modules\r\n\r\nRight? If that's the case, I think we can explore how to do it in Syro. It could be similar to that approach, or it could be something new. Let me know if we are talking about the same feature. Thanks!"}}
{"actor":{"display_login":"soveran"}}