From: Daniel Moore Date: 2009-12-04T16:00:48+09:00 Subject: [QUIZ][SUMMARY] Enumerable ObjectSpace (#222) --00c09f972a55c00fcb0479e1aa9e Content-Type: text/plain; charset=ISO-8859-1 (Sorry for the delays!) There were many great solutions to this week's quiz. James Coglan provides us with a compact solution using `method_missing`. class << ObjectSpace def method_missing(sym, *args, &block) mod = args.first.is_a?(Module) ? args.shift : nil enum = enum_for(*[:each_object, mod].compact) enum.__send__(sym, *args, &block) end end When calling an `Enumerable` method like `map` or `each` on `ObjectSpace` it will trigger `method_missing` as James's solution does not have `ObjectSpace` include the `Enumerable` methods directly. The first argument, if present and a `Module` will be extracted. An enumerator is then created using `enum_for` and passing the given `Module`, if present, to the `each_object` method of `ObjectSpace`. The original method invoked that brought us into method missing in then invoked on the new enumerator with the remaining arguments and block. This will work for `map` as well as `inject` as long as the first argument is a `Module`. Methods such as `map` and `each` may be called with no `Module` given, in which case the block is called once for each living, nonimmediate object in the Ruby process. The density of meta-programming in James's solution is a paragon of virtue and a good test of one's meta-programming knowledge. Benoit Daloze's solution uses meta-programming to define new methods that accept a `Module` parameter for all the 0 arity methods in `Enumerable`. `each` is also redefined to accept a `Module` parameter, though this is not used by the redefined methods, they use `to_enum` and `select` to filter out all instances of the given `Module`. objects = to_enum.select { |o| o.is_a? mod } Robert Klemme added an `arg` method to `ObjectSpace` which stored the parameter in a thread local stack variable, so that calls may be nested. Robert's `arg` method takes a block which is evaluated within the context of `ObjectSpace`. The `each` method is defined to call `each_object` with the parameter given by the top of the thread local stack variable. Stefano Crocco and Intransition also gave some good solutions, view the attachment[1] for full details. Thank you everyone for you solutions to this week's quiz. It was fun and really mind stretching. Keep the suggestions coming! [1]: http://rubyquiz.strd6.com/quizzes/222.tar.gz --00c09f972a55c00fcb0479e1aa9e Content-Type: application/x-gzip; name="222.tar.gz" Content-Disposition: attachment; filename="222.tar.gz" Content-Transfer-Encoding: base64 X-Attachment-Id: f_g2slrjdx0 H4sIAMuxGEsAA+0ba3PbxtGf8Ss25rQmHQrlm1OOFSd13EmaSdKJNZMPGg11BI7kRQCOxUMyLLK/ vbv3AEBSlO1UotMaO2OTBO729v0C1Ov1/vLkkaGDMB4O6bM7HnaqnxaedLv9zoj+DUdPOt3OqD96 AsPHJowgS1IWAzzxWSR4cHjd++7/j0IP9f99lMYsSkQqZPQYxvDh+u8Ou13Sf7/f7db6PwaQ/v/G IylS+JYF8h1/BAP4cP13+sNBj/TfG4xr/R8DSP+/yBmPU/gh4GH4qfXfGw6U/kedWv/HANL/m5TP WSThVSw9Tz68AXyE/nvjQZ/0P+j1av0fA0j//2AhT+CVXATsE+f/Tq+j439nMKz1fwwg/SdZGLI4 d9O36aOcQQoeDQaH9D/oo7K36/8+WsIT6DwKNTvwmev/bMljDjf0X8iiHBYxZykkMsioG0gglZAu RYIr+NWzBP6ViXeu41QjBqxieS18/J3hMpEugYEnwxXzSjx4S0QLuAx5upT+NBQJ/b50wXEAwQtY ksCLF/Dz7DfupW9wL1c3AHw+h+1dzSQP2/CcxYukDX+eBdK7apnFAKH0AU6BbrpzESepK5Ipe9n8 UfpZwFvwUt9KlmKewgQiERRbeZSFuJU+pnMZN5+fTzjzllOpaGoT6gvXMNba2uVOpwmP/On0HtLw vmM/nV+XPAKPBQEJBSV4+Rqx8JjNAn5puIVAXHEUGFtdgozhkkjBb7i2IqNLwLL9RgQBpLFYLHi8 J2FgCShloe4KZfgSlRXJFJbsmu8ijLwg8zkqnd9FVgK+iHF1kLuApgNKxiRTXBihkMQczYGjNPBi 5KMlXGrJX2oyZxz4W2w2vZT7LnwTKfHhCSmyiEaWKrmQBXLfmozVx6VCuGKKL0XeQlzjcntA9ey2 NluuxWY0WEhWzrd51pxIlKCIWGBXiehaXiEZ6RL9YRbLbLFMycJFhLjNGiNlvKZJt3uk+g0Rv6ky qHyDrsc8ZCJSujeCSxRzymCIGvI3EteNjK9gTupXdsDIDfEyfl6KSPOE3wNJmJT0dvRBMi1V4MKP RodJ5i0VFo0Wjzb2FbKcdESmiWwogrEuLHSoJN4mdm+WAlF4LNGWoiin08xOGXlcEU5o0ZSvkdk2 oooEdhi+QP2CVooRHfySzXIKJB5PEq0Pn9NEIidtobTZCd5cxCwMjbz3jFqxumIxW+AP3HQt4jTj xgoXErWVchQN3pERx417SK8ieYO0LzjGt62OuHpKlvA7tqJFYJwSkVa59RRlOczz+CqtOgLRiEvQ WUlAjJwX2e2g0ohdu1lsRwXXaojYDBKJNqRP9Onwew5BV1iS7eooLrTfIxdobbkxRovIHE07eE5r 4DKVUzJgYyMJD5TN4YlzERAHMksVByLCLIo6T0i++77p6jCvVZ5gkDV4XY0RbmEt1yB1rFYxfOM4 W10pMN9HEilWonEXroyUbIcvbZcJuptyXV6RNkqU4SWMLhhcJRoqLmNotdcoeJJxG7WsdUZGnFhf iNBqKFhpctAWtglgV5wMTzuAPh2FzK9ZkKkoRj5kbNyTUYrR70D8sR5ook8CFf0SQTuxrAgmJYNa 5katqVxZXdzDMypmu/lTiq7OA7W1LShRJBL1oDypKA/a6GZo8XQKSxHzUkUdsut5hiT76CgiSPCU syWLriCXGYqGxzm6oFpFF+6vNeB7zHAYquZZpGhDVoIA3UTg9ySNeeqheBcu/MD5StGRZJgIE40Q szXe/ML51EXWHxh26v9/P8YZ76n/e1jvm/q/1xuPO3r+M6jr/2PAJ67//8CVMIZqTllvKwvXNW9d 8/6f1rx1lvwcYe/5rzUuN5491Bnvm/+NhwP7/Hc07NL8fzjsjer8fwyIOaZ0TP7PyqD9zHEaOiCr +JKIcBVQAFefFGKZCj6mu/Cw1YIyR1L3hnETMVBfGgRSdwdFTyxVy1TktRPqMOKZQAOM80pq0LkM sWSRz+Mgp2DVUIGVoq3JF4GYqW2qKX9dJh1Cnnho0bi/Qhn2MYKaO+ppsKXIqRfKKa4meeS5TgNX //Tz2WtM0fkWQzrvmcom4gtkH4sF3a4jNiofiJWSekTkZ1wJIJyJRUYLTcwvspQnsyh14Y3cEk9D pzjFQeOdWBEmSVTptKgrMZa3YYaNt1JMru/oVJjTajyppB7Zgu/kDTVdlYOgga2l31bHCOppWSAQ QwP7NTXqVNXQjGN2D5mvGKFDEBUmLEzk8lolJFQTip8HuZ4nyBWZBRYTZUeqtKyqQ53BsJNmqom3 axHlFc8RuV/Z1ZyIeUQd4ulX4Lpuy4V/Bpyy7pXp8fCrL+ZzrFkp5SK/1A1qBQJsGTRNYp+ZG3rI fKa+QzHnLEU1mXxTUaCdPWPNkgoUzzveZHHcMncAvsZfatAcm0s02C23kak2o3I5rnPp2i2s+Rpy jCR+k38ZtWCzs119qm8poj9zsZ5qnnfbvXb/QmNLXU8GNDVpDvSFBorpfNgetccXuFO7X4UtB4xL QsmeY8lMeDB3b2K2mvJiw1TbSNPYSoRagZZjxtg0IS+v24t4Aa9XrM7Ogyyu0I7BtddoHK76YTGr ukrffoEcdczlG6oxO8W4XSlxSuMV+NNtcVXx0rgNN81i+J4HPpRTejOoV3N9NdU3U/qWq3ftLrfT eoJNlZLuA1Cir6sqnb6axxXnHbT1xq2SwOaira/Z36570r24l5sCnWXpwPF3ccaDhD+4hH8PHdVn JPTlsEUlzTlDqlvKqSjqrcO11dMhczbHF9gb8COlIv6WhqeU0ah4V5ERmnuBXmNpldNWg8KGLxvY XX3d3IXqEy2XUDdfkXzbYGLc6VcB5gif3XY3LdDBAc3ASOS/3l/4udpZ0USLkM+zNMNASYPe58+R jwReGhFiV/kdS9CnT82jNDzTNLf2l4sbXtpIXerVRu7KQp8HGNb3l6oVK7mi08rVPFyl+cti0QGv VfyYw3Zsa8uY792+va1ie4o6yojGdmBiE+OEdpL10DJlSA34Vbe4LG3r+aNtztBSGlhdUxGlM/XE cQ486Lw/GRlidF9Zae41AasM83DVSrC/1UaiDMJbg+eqGL65s8Hbf//v4RuA99T/3V6/mP+N+n16 /2M4GHbr+v8YYGqDbXs0o69KEeFUyhp6PnNKj863n3GjG6tfUzUxqYQSXG+e7OiZSumdpS0T0pZ5 DqRHQlTnN2Xr7iRV2Xn/JuvV5Wbz6Kni7Pp/LYjpPIs85b4qYhDfzXuy0Mn5xOC7aFUeZoVrXVkV 1Y9r6p5T6MBG56zbImUVSFXSffHi5M3ZL0XkVkn0gMTvl+5HPW27Q8Z7+3dkWqxw6eWH5oQo3abP rtT8bD42Xn1q1/gsYP/93+PH/8G4fP+33+vq+F/Pf44CjS8gzmZ5969Uyrz6+dvXZZHyvhrFJgWs qZqMPF97vX7CjL2reuzselmMfXp6PpnKhBqU6QWs16dwflEudlcZFptMV+UzvhCRDW/VyNi0B/Ao wbrVLDEI5GonoFcTlt3IkKpm8yBduspdr010akHMEy+zudGcXUlZVZ4x2m9XhWev35w5zt+lxDPf pHHmpdTKw+StM5eSgmqz67rdTovCH9yuxRpwrVoiNo6DJ2dBOlXT+9OtaImU0kpsefC8Fejdb9fw lnLTCpdtiPXdHUgBTWDUJpIZ/ZqqERSi1zOnZqel+qgkC9sgbTMVM4HtwdNImk1PIYsCjuZhMFKH IK0qshC+NB1y0WSpcP/0J/UShd2kDp5gaqsSsnlaaq7g6imGpcZtydtTm0SgIiF6u0CplKRn5FIV QMnfreJubSlVyNzfJNqb82EyVq6htn1qv30ouOP9/wdPAO+J/53xoGvr/3GvT3//MRz1xnX8Pwbc Uf87UMyj7xvqJXCiq9xVNguEZ686h/oHc39rYnO4/t0qgCuv1F6ZYPP1dOotJVaeU52uKjll/yY2 3OVrv2aNyjMYCVY8vgO9zTK7qIpMc8e0Spe56qdTGa/qpxZBoiv4vSxCdzDn7JxzftK9aN1Sna5m xSA3FvVDNP0V2Pv7j+M//+v0x8Pi/Z/BSPl/bzSs/f8YcGAi9RGv3f/OV+4//nX7D3nVvqjAPsBD 6g6zhhpqqKGGGmqooYYaaqihhhpq+CzgP8k8tsQAUAAA --00c09f972a55c00fcb0479e1aa9e--