[Facets] missing feature? Object#deep_map

37 views
Skip to first unread message

Guido De Rosa

unread,
Oct 5, 2010, 1:15:25 PM10/5/10
to facets-u...@rubyforge.org
Hi,

Consider a deeply nested structure made up of hashes and arrays,
something like:

o = {
'a' => C.new,
'b' => C.new,
'c' => [
C.new,
C.new,
{
'a' => C.new,
'b' => C.new,
'c => {
'a' => C.new,
'b' => [C.new, C.new, C.new]
}
}
]
}


Where C.new is just a placeholder/example for any kind of object which
does not behave like a Enumerable or a Hash (i.e. does not
respond_to :each or :each_pair, it's just "atomic content")

Suppose you want to create another structure were any of such
"content" is replaced by the result of a block call:

o.deep_map {|x| x.object_id}

such deep_map method should return something like:

{
'a' => 8748340,
'b' => 8746940,
'c' => [
8745260,
8742640,
{
'a' => 8723520,
# and so on...

Is there anything like that in Ruby Facets?

Thanks,
Guido

P.S.: in doubt, I have just reinvented-my-wheel ;-)
http://github.com/gderosa/onboard/blob/master/lib/onboard/extensions/object.rb#L27

_______________________________________________
facets-universal mailing list
facets-u...@rubyforge.org
http://rubyforge.org/mailman/listinfo/facets-universal

Trans

unread,
Oct 5, 2010, 2:15:49 PM10/5/10
to facets-u...@rubyforge.org

No, I don't think so. Facets #recursive method might help though.
Albeit that's in the latest 2.9.0 version that hasn't been release yet
--but it will be within days.

Also, you might ask for some golf to be played on this idea on ruby-
talk. I would not be surprised if someone couldn't figure out how to
knock the code for this down to one to two lines.

Guido De Rosa

unread,
Oct 5, 2010, 4:21:19 PM10/5/10
to facets-u...@rubyforge.org

> > Is there anything like that in Ruby Facets?
>
> No, I don't think so. Facets #recursive method might help though.

Well, I was thinking about contributing my method to Facets, forking
the repo and following the other guidelines (tests, rdoc comments
etc.). It will take some time but looks doable. Or do you think it
would be useless/redundant compared to #recursive?

G.

Trans

unread,
Oct 6, 2010, 8:30:24 AM10/6/10
to facets-u...@rubyforge.org
On Oct 5, 4:21 pm, Guido De Rosa <guidoder...@gmail.com> wrote:
> > > Is there anything like that in Ruby Facets?
>
> > No, I don't think so. Facets #recursive method might help though.
>
> Well, I was thinking about contributing my method to Facets, forking
> the repo and following the other guidelines (tests, rdoc comments
> etc.). It will take some time but looks doable. Or do you think it
> would be useless/redundant compared to #recursive?

And I was thinking of adding it to Facets :)

But I need to understand it better to do so. Basically there 's a
weighing between general utility and difficulty to achieve without the
method. Which is why I suggested posting it to ruby-talk for a round
of golf and comments.

I wouldn't be surprised if there were a way for #recursive (or
#recursively) to handle it fairly concisely, but it's not obvious to
me at the moment. The difficulty lies in the fact that it applies to
both Arrays and Hashes.

(side note) I always wondered if it was a mistake that Hash#each did
not just iterate over the values, and a different set of iterators
could have been used to iterate over key,value pairs. This would have
created better polymorphism between Array and Hash.

In any case, I'd be happy to add it to Facets if you test it and vet
it on ruby-talk.

Guido De Rosa

unread,
Oct 6, 2010, 11:10:01 AM10/6/10
to facets-u...@rubyforge.org
> Which is why I suggested posting it to ruby-talk for a round
> of golf and comments.

http://www.ruby-forum.com/topic/218112

I'm waiting for replies. Hopefully, after some fruitful discussion i
will fork the git repository and do the rest of the work.

Guido De Rosa

unread,
Oct 11, 2010, 5:42:23 AM10/11/10
to facets-u...@rubyforge.org
BTW, just patched #recurse to properly traverse multiple classes
(Array, Hash), take a look at my "recurse" branch:

http://github.com/gderosa/facets/commits/recurse

G.

Trans

unread,
Oct 12, 2010, 1:10:17 PM10/12/10
to Facets
On Mon, Oct 11, 2010 at 5:42 AM, Guido De Rosa <guido...@gmail.com> wrote:
> BTW, just patched #recurse to properly traverse multiple classes
> (Array, Hash), take a look at my "recurse" branch:
>
> http://github.com/gderosa/facets/commits/recurse

Excellent. I'm just about to release 2.9.0 and I will pull this in before I do.

Super Thanks!

Guido De Rosa

unread,
Oct 14, 2010, 3:41:29 AM10/14/10
to facets-u...@rubyforge.org
> Excellent. I'm just about to release 2.9.0 and I will pull this in before I do.

Well :-)

...but we still have the problem of implementing "deep_map" and
friends via #recursive or #recursively (although the above patch
*might* help). Right now
I don't have the time to figure this out in a proper and *concise*
way. So I ended up with my original implementation , which also has
the advantage of being more duck-typed.

Two methods: #deep_map_values and #deep_rekey which treat keys and
values separately (unlike Hash#map).

The code is here:

http://github.com/gderosa/onboard/blob/e9bf3939f55617037911a531b37c72b261a7f79a/lib/onboard/extensions/object/deep.rb

This is the best I can do right now, if there's some interest in the
code as is
I may go on, adding tests&docs, otherwise I'll keep using it hard-
coded in my own project.

In any case, thanks for this awesome project :)

Guido

Reply all
Reply to author
Forward
0 new messages