Maybe allow more expressions to be used in PLUCK, similar to what is possible in MAP?
vlazar opened this issue · 1 comments
Current PLUCK function implemented in #221 only allows to get values from hash by property name (same as Rails's pluck).
MAP function OTOH allows more:
calculator.evaluate!('map(users, u, u.address.state)', users: [
{ name: "Bob", age: 44, address: { state: "CA" } },
{ name: "Jane", age: 27, address: { state: "NE" } }
]) # => ["CA", "NE"]
calculator.evaluate!('map(users, u, u.hobbies[0])', users: [
{ name: "Bob", age: 44, hobbies: ["guitar", "baseball"] },
{ name: "Jane", age: 27, hobbies: ["drawing", "singing"] }
]) # => ["guitar", "drawing"]
With my naive implementation in 677eee3 the first case also worked with PLUCK:
calculator.evaluate!('pluck(users, address.state)', users: [
{ name: "Bob", age: 44, address: { state: "CA" } },
{ name: "Jane", age: 27, address: { state: "NE" } }
]) # => ["CA", "NE"]
The second case with u.hobbies[0]
was failing however due to naive handling here 677eee3#diff-ed127330f002c385f66a40dd7a996f0bce2a52fa32063f15de1c49b8215d35f8R23
calculator.evaluate!('pluck(users, hobbies[0])', users: [
{ name: "Bob", age: 44, hobbies: ["guitar", "baseball"] },
{ name: "Jane", age: 27, hobbies: ["drawing", "singing"] }
]) # => NoMethodError: private method `identifier' called for #<Dentaku::AST::Access:0x00007f9da8fa73d0>
That's because Dentaku
- parses
u.address.state
as#<Dentaku::AST::Identifier:0x00007fae136e8070 @case_sensitive=nil, @identifier="u.address.state">
- but parses
u.hobbies[0]
as#<Dentaku::AST::Access:0x00007fae136f96e0 @structure=#<Dentaku::AST::Identifier:0x00007fae136f97f8 @case_sensitive=nil, @identifier="u.hobbies">, @index=#<Dentaku::AST::Numeric:0x00007fae136f9780 @value=0, @type=:numeric>>
The second argument for PLUCK probably shouldn't be treated as an arbitrary expression, that would most likely be too hard (or not possible) to make it work.
I still wonder if allowing some of of the cases like address.state
and hobbies[0]
(basically limit the allowed syntax to digging some data from an array of hashes) would make sense?
Some thoughts:
- allowing things like
pluck(users, address.state)
can be non obvious, it's more than Rails's pluck allows to do (jus pick a value by key) - making things like
pluck(users, age > 21)
(same asmap(users, u, u.age > 21)
) to work could be too hard - can be confusing, since if someone sees example like
pluck(users, address.state)
then something likepluck(users, age > 21 and address.state = "CA")
would probably be expected to work too?
Gonna close it. I've given this some more thoughts and now I think that a simple PLUCK is enough and actually better, than some weird limited version of MAP, or complex implementation. It's not worth it.