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

add inferred nil to html_builder when type ends with ? #980

Merged
merged 2 commits into from
Nov 26, 2019

Conversation

bdtomlin
Copy link
Contributor

Purpose

Allow the more intuitive way to specify optional "needs" in html builder. #804

Description

Instead of

needs user : User? = nil

you can now just specify

needs user : User?

Checklist

  • - An issue already exists detailing the issue/or feature request that this PR fixes
  • - All specs are formatted with crystal tool format spec src
  • - Inline documentation has been added and/or updated
  • - Lucky builds on docker with ./script/setup
  • - All builds and specs pass on docker with ./script/test

Copy link
Member

@paulcsmith paulcsmith left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Woo hoo 🎉

@paulcsmith paulcsmith merged commit ed8d366 into luckyframework:master Nov 26, 2019
@bdtomlin bdtomlin deleted the comp-needs branch December 4, 2019 19:16
@wezm
Copy link
Contributor

wezm commented Dec 23, 2019

I think this change broke my code. I have a component:

class Shared::LayoutHead < BaseComponent
  needs page_title : String
  needs app_js : Bool
  needs admin : Bool
  needs extra_css : String?
  # This is used by the 'csrf_meta_tags' method
  needs context : HTTP::Server::Context
  needs categories : CategoryQuery

  def render
    head do
      utf8_charset
      title "#{@page_title} – Read Rust"
      css_link asset("css/app.css"), data_turbolinks_track: "reload"
      js_link asset("js/app.js"), defer: "true", data_turbolinks_track: "reload" if @app_js

      if @admin
        css_link asset("css/admin.css"), data_turbolinks_track: "reload"
        js_link asset("js/admin.js"), defer: "true", data_turbolinks_track: "reload"
      end
      meta name: "turbolinks-cache-control", content: "no-cache"
      csrf_meta_tags
      responsive_meta_tag

      @categories.each do |category|
        tag "link", href: RssFeed::Show.with(category.slug).url, rel: "alternate", title: "Read Rust - #{category.name}", type: "application/rss+xml"
      end

      meta content: "Read Rust collects interesting posts related to the Rust programming language.", name: "description"
      css_link dynamic_asset(@extra_css), data_turbolinks_track: "reload" if @extra_css
    end
  end
end

This previously compiled on Lucky 0.18.0. On 0.18.2 the compiler reports this error. I'm using a picture here because useful information is lost without the colour and emphasised text.

Screenshot from 2019-12-23 11-25-17

The issue is the addition of the inferred nil default value because now there is an argument with a default value that precedes ones without, which is not allowed (see this test in the Crystal repo).

Before this change there was no default value on the extra_css parameter so it compiled ok. It's possible to work around the error by reordering the needs calls so that ones that are non-nil come first but this does not seem very intuitive. Plus, the error is extremely unhelpful as it does not point to the actual file where the error is happening. It wasn't until I discovered the --error-trace argument to the compiler that I was able to work out what was going on. This seems like it might be something that would trip up folks new to the framework. This is was the error is without --error-trace:

There was a problem expanding macro 'generate_needy_initializer'

Code in macro 'finished'

 1 | generate_needy_initializer
     ^
Called macro defined in lib/lucky/src/lucky/html_builder.cr:46:3

 46 | macro generate_needy_initializer

Which expanded to:

 > 35 |
 > 36 |
 > 37 |            @context : HTTP::Server::Context,
                   ^
Error: argument must have a default value

@paulcsmith
Copy link
Member

paulcsmith commented Dec 23, 2019 via email

@wezm
Copy link
Contributor

wezm commented Dec 23, 2019

Wesley, could you open a new issue for this so we can track it more easily?

👍 Done

@wezm
Copy link
Contributor

wezm commented Dec 23, 2019

I think what we need to do is sort the “needs” to put them at the end when there is a default nil value.

I can't actually do this as my MainLayout has needs current_user : User?, so anything that inherits from that layout and has a non-optional needs call hits the error, but the order can't be changed. I'm in no rush to upgrade, enjoy your holiday @paulcsmith.

@paulcsmith
Copy link
Member

paulcsmith commented Dec 23, 2019 via email

@wezm
Copy link
Contributor

wezm commented Dec 23, 2019

Oh right, yep that makes sense.

@bdtomlin
Copy link
Contributor Author

@paulcsmith

It looks like this is an issue with the order of needs in general. You cannot have a needs that has defaults before needs that don't have defaults.

Thanks for the great error report @wezm.

I'll create a PR for this.

@jwoertink
Copy link
Member

@bdtomlin I actually started looking at this, but I'm stuck. Maybe you'll have an easier time then me?

I run in to this issue when trying to sort these
https://play.crystal-lang.org/#/r/89e3

I was trying to sort the ASSIGNS here
https://github.com/luckyframework/lucky/blob/master/src/lucky/html_builder.cr#L47-L59

I did have an alternate version where I created 2 arrays. 1 for required and 1 for optional. Then had 2 separate for loops. It wasn't pretty though... However, we may have to go that route?

@jwoertink
Copy link
Member

oh, actually, I may have it. Got some help from the community 😄 I'll push this up in a second

@bdtomlin
Copy link
Contributor Author

@jwoertink, nice. Thanks! I look forward to seeing your solution :)

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

Successfully merging this pull request may close these issues.

4 participants