{"action":"created","issue":{"url":"https://api.github.com/repos/zeromq/zproject/issues/322","labels_url":"https://api.github.com/repos/zeromq/zproject/issues/322/labels{/name}","comments_url":"https://api.github.com/repos/zeromq/zproject/issues/322/comments","events_url":"https://api.github.com/repos/zeromq/zproject/issues/322/events","html_url":"https://github.com/zeromq/zproject/pull/322","id":118938370,"number":322,"title":"Problem: complicated fresh pointer handling in Ruby bindings","user":{"login":"paddor","id":8876,"avatar_url":"https://avatars.githubusercontent.com/u/8876?v=3","gravatar_id":"","url":"https://api.github.com/users/paddor","html_url":"https://github.com/paddor","followers_url":"https://api.github.com/users/paddor/followers","following_url":"https://api.github.com/users/paddor/following{/other_user}","gists_url":"https://api.github.com/users/paddor/gists{/gist_id}","starred_url":"https://api.github.com/users/paddor/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/paddor/subscriptions","organizations_url":"https://api.github.com/users/paddor/orgs","repos_url":"https://api.github.com/users/paddor/repos","events_url":"https://api.github.com/users/paddor/events{/privacy}","received_events_url":"https://api.github.com/users/paddor/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":null,"milestone":null,"comments":3,"created_at":"2015-11-25T22:59:29Z","updated_at":"2015-11-26T10:24:11Z","closed_at":"2015-11-25T23:04:26Z","pull_request":{"url":"https://api.github.com/repos/zeromq/zproject/pulls/322","html_url":"https://github.com/zeromq/zproject/pull/322","diff_url":"https://github.com/zeromq/zproject/pull/322.diff","patch_url":"https://github.com/zeromq/zproject/pull/322.patch"},"body":"Memory of fresh strings isn't free'd automatically when `FFI::Pointer` goes out of scope.\r\n\r\nSolution: Wrap it in an `FFI::AutoPointer`.\r\n\r\nConsider the following method API:\r\n\r\n```xml\r\n  <method name = \"encode\">\r\n      Encode a stream of bytes into an armoured string.\r\n      <argument name = \"data\" type = \"buffer\" />\r\n      <argument name = \"data size\" type = \"size\" />\r\n      <return type = \"string\" fresh = \"1\" />\r\n  </method>\r\n```\r\n\r\nThe corresponding C function might look like this:\r\n\r\n```c\r\n  char * foo_encode(const byte * data, size_t data_size)\r\n```\r\n\r\nNote that the return value is a \"fresh\" string, which means the caller is responsible for destroying it when finished with it. Also note that it's not a struct of the class defined in this API or any other class. It must be a C style, NULL-terminated string.\r\n\r\nIt would be nice to have the generated Ruby bindings to automatically release said memory as soon as its corresponding FFI::Pointer goes out of scope.\r\n\r\nLuckily, there's FFI::AutoPointer for this. One just has to subclass it and define its `.release` method appropriately. This commit defines it to call libc's `free()`. I believe this is okay, assuming:\r\n\r\n* libc is available on every system\r\n* no project-specific function has to be used to `free()` a C style string\r\n\r\nHonestly, I'm not 100% sure if this is a good idea. Are my assumptions valid?\r\n\r\nNote that:\r\n\r\n* this applies only to functions that have `char *` value, which is also marked \"fresh\"\r\n* automatic release is already done in Ruby bindings for \"freesh\" class objects (like `zmsg_t` objects) (but using the class' destructor, of course)"},"comment":{"url":"https://api.github.com/repos/zeromq/zproject/issues/comments/159869652","html_url":"https://github.com/zeromq/zproject/pull/322#issuecomment-159869652","issue_url":"https://api.github.com/repos/zeromq/zproject/issues/322","id":159869652,"user":{"login":"Asmod4n","id":791770,"avatar_url":"https://avatars.githubusercontent.com/u/791770?v=3","gravatar_id":"","url":"https://api.github.com/users/Asmod4n","html_url":"https://github.com/Asmod4n","followers_url":"https://api.github.com/users/Asmod4n/followers","following_url":"https://api.github.com/users/Asmod4n/following{/other_user}","gists_url":"https://api.github.com/users/Asmod4n/gists{/gist_id}","starred_url":"https://api.github.com/users/Asmod4n/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Asmod4n/subscriptions","organizations_url":"https://api.github.com/users/Asmod4n/orgs","repos_url":"https://api.github.com/users/Asmod4n/repos","events_url":"https://api.github.com/users/Asmod4n/events{/privacy}","received_events_url":"https://api.github.com/users/Asmod4n/received_events","type":"User","site_admin":false},"created_at":"2015-11-26T10:24:11Z","updated_at":"2015-11-26T10:24:11Z","body":"FFI::AutoPointer is roughly 20 times slower than manual managing."}}