Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

In Logic Less templates iteration with lambdas result in NoMethodError #783

Closed
daniels opened this issue Oct 6, 2017 · 3 comments
Closed

Comments

@daniels
Copy link

daniels commented Oct 6, 2017

I would have guessed that placing a lambda call in a list iteration would resolve just like any other slim instruction, but I haven't been able to get it to work.

See the following example code

require 'slim/logic_less'

SCOPE = {
  fn: ->(&block) { "<fn>#{block.call}</fn>" },
  string: "string variable",
  list: [ "list item 1", "list item 2", "list item 3" ],
}

def render(template_string)
  p Slim::Template.new { template_string }.render(SCOPE)
end


# Some example lambda calls

render %q{
== fn
  p literal
}
#=> "<fn><p>literal</p></fn>"

render %q{
== fn
  p = string
}
#=> "<fn><p>string variable</p></fn>"


# Some example list iterations

render %q{
- list
  p literal
}
#=> "<p>literal</p><p>literal</p><p>literal</p>"

render %q{
- list
  p = string
}
#=> "<p>string variable</p><p>string variable</p><p>string variable</p>"

render %q{
- list
  p = self
}
#=> "<p>list item 1</p><p>list item 2</p><p>list item 3</p>"


# Try to combine with the lambda wrapped in the list expressions, but all of these result
# in "undefined method `call' for nil:NilClass (NoMethodError)"

render %q{
- list
  == fn
    p literal
}
#=> raises NoMethodError
# Expected result:
#   "<fn><p>literal</p></fn><fn><p>literal</p></fn><fn><p>literal</p></fn>"

render %q{
- list
  == fn
    p = string
}
#=> raises NoMethodError
# Expected result:
#   "<fn><p>string variable</p></fn><fn><p>string variable</p></fn><fn><p>string variable</p></fn>"

render %q{
- list
  == fn
    p = self
}
#=> raises NoMethodError
# Expected result:
#   "<fn><p>list item 1</p></fn><fn><p>list item 2</p></fn><fn><p>list item 3</p></fn>"
@daniels daniels changed the title Iteration with lambdas result in NoMethodError Iteration with lambdas result in NoMethodError (Logic Less templates) Oct 6, 2017
@daniels daniels changed the title Iteration with lambdas result in NoMethodError (Logic Less templates) In Logic Less templates iteration with lambdas result in NoMethodError Oct 6, 2017
@andrewdsmith
Copy link

Looks like this is working as expected. When inside the list loop, self becomes each element of the array list, i.e. a string. So the fn is being sent to the string value from the array, hence NoMethodError. You would need to implement fn on each element of the array to get your desired behaviour. Possibly you could add the objects parent to the dictionary lookup somehow, but that seems likely to create more problems, the likes of which you're trying to avoid with logic-less templates.

@daniels
Copy link
Author

daniels commented May 19, 2022

Looks like this is working as expected. When inside the list loop, self becomes each element of the array list, i.e. a string. So the fn is being sent to the string value from the array, hence NoMethodError. You would need to implement fn on each element of the array to get your desired behaviour. Possibly you could add the objects parent to the dictionary lookup somehow, but that seems likely to create more problems, the likes of which you're trying to avoid with logic-less templates.

But string from the original scope is still accessible in the list iteration. From a user perspective (not implementation) it seems counter intuitive that fn is out of scope but string isn't.

@andrewdsmith
Copy link

Very good point! I guess you do want access to higher level scopes otherwise writing templates would be tortuous. Does seem like it's inconsistent.

@minad minad closed this as completed in 4ccd62e Sep 18, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants