165 Matching Annotations
  1. Apr 2025
    1. A lot of it feels like someone who doesn’t like the old code and wants to do it “right.” I can agree that the old code is ugly. But it will take an awful lot of effort to make a new implementation. It’s a lot like what happened to Elvis: A rewrite was going to make it much better, but it took so long, during which Vim added more features, that eventually there are not so many Elvis users. And the rewritten Elvis may have nice code, but users don’t notice that.
  2. Mar 2025
    1. The goal of Lucia v3 was to be the easiest and cleanest way to implement database-backed sessions in your projects. It didn't have to be a library. I just assumed that a library will be the answer. But I ultimately came to conclusion that my assumption was wrong. I don't see this change as me abandoning the project. In fact, I think it's a step forward. If implementing sessions wasn't easy, I wouldn't be deprecating the package. But why wouldn't a library be the answer? It seems like a such an obvious answer. One word - database. I talked about how database adapters were a significant complexity tax to the library. I think a lot of people interpreted that as maintenance burden on myself. That's not wrong, but the bigger issue is how the adapters limit the API. Adapters always felt like a black box to me as both an end user and a maintainer. It's very hard to design something clean around it and makes everything clunky and fragile, especially when you need to deal with TypeScript shenanigans.
    1. The figure of the grieving mother is a collectivity, with women characterized as part of a population of mothers with a collective experience of loss. Their dissent is practiced through invocations of a dead or imperiled soldier child, who signifies the claim to associative military masculinity. In contrast, the perspective of the returning veteran is grounded in individual experience. The film depicts women as caregivers, with their dissenting subjecthood derived from their relationships with men.
    2. this narrative of personal growth and triumph is complicated by the fact that Tomas's newfound power and authority are rooted in traditional masculine ideals. The film ultimately suggests that the military peace movement is shaped by masculinized privilege, which can be both productive and limiting.
  3. Feb 2025
  4. Jan 2025
  5. Nov 2024
  6. Sep 2024
  7. May 2024
  8. Nov 2023
    1. So then they put it into lib only to find that they have to manually require it. Then later realize that this also means they now have to reboot their server any time they change the file (after a painfully long debugging time of "why what aren't my changes working?", because their lib folder classes are now second-class citizens). Then they go down the rabbit hole of adding lib to the autoload paths, which burns them because rake tasks then all get eager loaded in production. Then they inevitably realize anything inside app is autoloaded and make an app/lib per Xavier's advice.
    2. I think the symmetry of the naming between lib and app/lib will lead a fresh Rails developer to seek out the answer to “Why are there two lib directories?", and they will become illuminated. And it will prevent them from seeking the answer to “How do I autoload lib?” which will start them on a rough path that leads to me advising them to undo it.
  9. Sep 2023
  10. Apr 2023
  11. Mar 2023
  12. Dec 2022
    1. If a contact ever reaches out and is no longer receiving messages because they accidentally marked one of your campaigns as spam, you can reach out to Product Support. We can remove them from the suppression list for you. 

      why not allow user to do it directly instead of force to contact support? If they'll remove it for you because you said the user asked you to... why not just let you remove the suppression yourself? Mailgun lets you directly delete suppressions via their API.

    1. Let’s say the recipient is considering unsubscribing. He or she may be too busy to search through the email to find the unsubscribe link, so he or she just clicks “Report as SPAM” to stop the emails from coming. This is the last thing any marketer wants to see happen. It negatively impacts sender reputation, requiring extra work to improve email deliverability. With the list-unsubscribe header, you will avoid getting into this kind of trouble in the first place.
  13. Nov 2022
    1. In v3, svelte-preprocess was able to type-check Svelte components. However, giving the specifics of the structure of a Svelte component and how the script and markup contents are related, type-checking was sub-optimal. In v4, your TypeScript code will only be transpiled into JavaScript, with no type-checking whatsoever. We're moving the responsibility of type-checking to tools better fit to handle it, such as svelte-check, for CLI and CI usage, and the VS Code extension, for type-checking while developing.
  14. Oct 2022
    1. I'm afraid you missed the joke ;-) While you believe spaces are required on both sides of an em dash, there is no consensus on this point. For example, most (but not all) American authorities say /no/ spaces should be used. That's the joke. In writing a line about "only one way to do it", I used a device (em dash) for which at least two ways to do it (with spaces, without spaces) are commonly used, neither of which is obvious -- and deliberately picked a third way just to rub it in. This will never change ;-)
    1. First and foremost, we need to acknowledge that even though the funding goal has been met–it does not meet the realistic costs of the project. Bluntly speaking, we did not have the confidence to showcase the real goal of ~1.5 million euros (which would be around 10k backers) in a crowdfunding world where “Funded in XY minutes!” is a regular highlight.

      new tag: pressure to understate the real cost/estimate

  15. Sep 2022
  16. Jul 2022
  17. Jun 2022
  18. Apr 2022
  19. Feb 2022
  20. Nov 2021
  21. Sep 2021
  22. Aug 2021
    1. Now consider we want to handle numbers in our known value set: const KNOWN_VALUES = Object.freeze(['a', 'b', 'c', 1, 2, 3]) function isKnownValue(input?: string | number) { return typeof(input) === 'string' && KNOWN_VALUES.includes(input) } Uh oh! This TypeScript compiles without errors, but it's not correct. Where as our original "naive" approach would have worked just fine. Why is that? Where is the breakdown here? It's because TypeScript's type system got in the way of the developer's initial intent. It caused us to change our code from what we intended to what it allowed. It was never the developer's intention to check that input was a string and a known value; the developer simply wanted to check whether input was a known value - but wasn't permitted to do so.
  23. Jun 2021
  24. May 2021
  25. Apr 2021
    1. Of course you must not use plain-text passwords and place them directly into scripts. You even must not use telnet protocol at all. And avoid ftp, too. I needn’t say why you should use ssh, instead, need I? And you also must not plug your fingers into 220 voltage AC-output. Telnet was chosen for examples as less harmless alternative, because it’s getting rare in real life, but it can show all basic functions of expect-like tools, even abilities to send passwords. BUT, you can use “Expect and Co” to do other things, I just show the direction.
    2. But in all this incongruous abundance you'll certanly find the links to expect It's just what is wanted: the tool, which is traditionally used to communicate automatically with interactive programs. And as it always occurs, there is unfortunately a little fault in it: expect needs the programming language TCL to be present. Nevertheless if it doesn't discourage you to install and learn one more, though very powerful language, then you can stop your search, because expect and TCL with or without TK have everything and even more for you to write scripts.
    1. “Who cares? Let’s just go with the style-guide” — to which my response is that caring about the details is in the heart of much of our doings. Yes, this is not a major issue; def self.method is not even a code smell. Actually, that whole debate is on the verge of being incidental. Yet the learning process and the gained knowledge involved in understanding each choice is alone worth the discussion. Furthermore, I believe that the class << self notation echoes a better, more stable understanding of Ruby and Object Orientation in Ruby. Lastly, remember that style-guides may change or be altered (carefully, though!).
  26. Mar 2021
  27. afarkas.github.io afarkas.github.io
    1. Webshim is also more than a polyfill, it has become a UI component and widget library. Webshim enables a developer to also enhance HTML5 capable browsers with more highly customizable, extensible and flexible UI components and widgets.

      And now that it's deprecated (presumably due to no longer needing these polyfills), not only do the polyfills go away (no longer maintained), but also these unrelated "extras" that some of us may have been depending on are now going away with no replacement ...

      If those were in a separate package, then there would have been some chance of the "extras" package being updated to work without the base webshims polyfills.

      In particular, I was using $.webshims.addCustomValidityRule which adds something that you can't do in plain HTML5 (that I can tell), so it isn't a polyfill...

  28. Feb 2021
    1. For branching out a separate path in an activity, use the Path() macro. It’s a convenient, simple way to declare alternative routes

      Seems like this would be a very common need: once you switch to a custom failure track, you want it to stay on that track until the end!!!

      The problem is that in a Railway, everything automatically has 2 outputs. But we really only need one (which is exactly what Path gives us). And you end up fighting the defaults when there are the automatic 2 outputs, because you have to remember to explicitly/verbosely redirect all of those outputs or they may end up going somewhere you don't want them to go.

      The default behavior of everything going to the next defined step is not helpful for doing that, and in fact is quite frustrating because you don't want unrelated steps to accidentally end up on one of the tasks in your custom failure track.

      And you can't use fail for custom-track steps becase that breaks magnetic_to for some reason.

      I was finding myself very in need of something like this, and was about to write my own DSL, but then I discovered this. I still think it needs a better DSL than this, but at least they provided a way to do this. Much needed.

      For this example, I might write something like this:

      step :decide_type, Output(Activity::Left, :credit_card) => Track(:with_credit_card)
      
      # Create the track, which would automatically create an implicit End with the same id.
      Track(:with_credit_card) do
          step :authorize
          step :charge
      end
      

      I guess that's not much different than theirs. Main improvement is it avoids ugly need to specify end_id/end_task.

      But that wouldn't actually be enough either in this example, because you would actually want to have a failure track there and a path doesn't have one ... so it sounds like Subprocess and a new self-contained ProcessCreditCard Railway would be the best solution for this particular example... Subprocess is the ultimate in flexibility and gives us all the flexibility we need)


      But what if you had a path that you needed to direct to from 2 different tasks' outputs?

      Example: I came up with this, but it takes a lot of effort to keep my custom path/track hidden/"isolated" and prevent other tasks from automatically/implicitly going into those steps:

      class Example::ValidationErrorTrack < Trailblazer::Activity::Railway
        step :validate_model, Output(:failure) => Track(:validation_error)
        step :save,           Output(:failure) => Track(:validation_error)
      
        # Can't use fail here or the magnetic_to won't work and  Track(:validation_error) won't work
        step :log_validation_error, magnetic_to: :validation_error,
          Output(:success) => End(:validation_error), 
          Output(:failure) => End(:validation_error) 
      end
      
      puts Trailblazer::Developer.render o
      Reloading...
      
      #<Start/:default>
       {Trailblazer::Activity::Right} => #<Trailblazer::Activity::TaskBuilder::Task user_proc=validate_model>
      #<Trailblazer::Activity::TaskBuilder::Task user_proc=validate_model>
       {Trailblazer::Activity::Left} => #<Trailblazer::Activity::TaskBuilder::Task user_proc=log_validation_error>
       {Trailblazer::Activity::Right} => #<Trailblazer::Activity::TaskBuilder::Task user_proc=save>
      #<Trailblazer::Activity::TaskBuilder::Task user_proc=save>
       {Trailblazer::Activity::Left} => #<Trailblazer::Activity::TaskBuilder::Task user_proc=log_validation_error>
       {Trailblazer::Activity::Right} => #<End/:success>
      #<Trailblazer::Activity::TaskBuilder::Task user_proc=log_validation_error>
       {Trailblazer::Activity::Left} => #<End/:validation_error>
       {Trailblazer::Activity::Right} => #<End/:validation_error>
      #<End/:success>
      
      #<End/:validation_error>
      
      #<End/:failure>
      

      Now attempt to do it with Path... Does the Path() have an ID we can reference? Or maybe we just keep a reference to the object and use it directly in 2 different places?

      class Example::ValidationErrorTrack::VPathHelper1 < Trailblazer::Activity::Railway
         validation_error_path = Path(end_id: "End.validation_error", end_task: End(:validation_error)) do
          step :log_validation_error
        end
        step :validate_model, Output(:failure) => validation_error_path
        step :save,           Output(:failure) => validation_error_path
      end
      
      o=Example::ValidationErrorTrack::VPathHelper1; puts Trailblazer::Developer.render o
      Reloading...
      
      #<Start/:default>
       {Trailblazer::Activity::Right} => #<Trailblazer::Activity::TaskBuilder::Task user_proc=validate_model>
      #<Trailblazer::Activity::TaskBuilder::Task user_proc=validate_model>
       {Trailblazer::Activity::Left} => #<Trailblazer::Activity::TaskBuilder::Task user_proc=log_validation_error>
       {Trailblazer::Activity::Right} => #<Trailblazer::Activity::TaskBuilder::Task user_proc=save>
      #<Trailblazer::Activity::TaskBuilder::Task user_proc=log_validation_error>
       {Trailblazer::Activity::Right} => #<End/:validation_error>
      #<Trailblazer::Activity::TaskBuilder::Task user_proc=save>
       {Trailblazer::Activity::Left} => #<Trailblazer::Activity::TaskBuilder::Task user_proc=log_validation_error>
       {Trailblazer::Activity::Right} => #<End/:success>
      #<End/:success>
      
      #<End/:validation_error>
      
      #<End/:failure>
      

      It's just too bad that:

      • there's not a Railway helper in case you want multiple outputs, though we could probably create one pretty easily using Path as our template
      • we can't "inline" a separate Railway acitivity (Subprocess "nests" it rather than "inlines")
    2. step :direct_debit

      I don't think we would/should really want to make this the "success" (Right) path and :credit_card be the "failure" (Left) track.

      Maybe it's okay to repurpose Left and Right for something other than failure/success ... but only if we can actually change the default semantic of those signals/outputs. Is that possible? Maybe there's a way to override or delete the default outputs?

    1. While Trailblazer offers you abstraction layers for all aspects of Ruby On Rails, it does not missionize you. Wherever you want, you may fall back to the "Rails Way" with fat models, monolithic controllers, global helpers, etc. This is not a bad thing, but allows you to step-wise introduce Trailblazer's encapsulation in your app without having to rewrite it.
  29. Jan 2021
  30. Dec 2020
    1. No more waiting around for pull requests to be merged and published. No more forking repos just to fix that one tiny thing preventing your app from working.

      This could be both good and bad.

      potential downside: If people only fix things locally, then they may be less inclined/likely to actually/also submit a merge request, and therefore it may be less likely that this actually (ever) gets fixed upstream. Which is kind of ironic, considering the stated goal "No more waiting around for pull requests to be merged and published." But if this obviates the need to create a pull request (does it), then this could backfire / work against that goal.

      Requiring someone to fork a repo and push up a fix commit -- although a little extra work compared to just fixing locally -- is actually a good thing overall, for the community/ecosystem.

      Ah, good, I see they touched on some of these points in the sections:

      • Benefits of patching over forking
      • When to fork instead
  31. Nov 2020
  32. Oct 2020
    1. Form validation can get complex (synchronous validations, asynchronous validations, record validations, field validations, internationalization, schemas definitions...). To cope with these challenges we will leverage this into Fonk and Fonk Final Form adaptor for a React Final Form seamless integration.
    1. I'm okay with an overall design that allows people to plugin the parts they need in order to be able to generically support a compile-to-javascript language, but to bake in support for one singular solution because its popular is simply bad engineering.
  33. Sep 2020
    1. DX: start sapper project; configure eslint; eslint say that svelt should be dep; update package.json; build fails with crypt error; try to figure what the hell; google it; come here (if you have luck); revert package.json; add ignore error to eslint; Maybe we should offer better solution for this.
  34. Jul 2020
    1. Matz, alas, I cannot offer one. You see, Ruby--coding generally--is just a hobby for me. I spend a fair bit of time answering Ruby questions on SO and would have reached for this method on many occasions had it been available. Perhaps readers with development experience (everybody but me?) could reflect on whether this method would have been useful in projects they've worked on.
  35. Jun 2020
    1. OK, so what about regular messages? Turns out they are not encrypted after all. Where Signal implements the security and privacy protocols right from the start, Telegram separates the two and offers an additional option. The problem is that not everyone is aware of the Secret Chat option and first-time users may send sensitive information in the regular chat window unknowingly.
  36. May 2020
  37. Apr 2020
    1. The only goal is correctness. Code style is not a consideration. Providing the level of configuration necessary to make everyone happy would be a huge distraction from the main purpose. After conversion, I recommend using rubocop's awesome --auto-correct feature to apply your preferred code style.
  38. Mar 2020
    1. Earlier this year it began asking Europeans for consent to processing their selfies for facial recognition purposes — a highly controversial technology that regulatory intervention in the region had previously blocked. Yet now, as a consequence of Facebook’s confidence in crafting manipulative consent flows, it’s essentially figured out a way to circumvent EU citizens’ fundamental rights — by socially engineering Europeans to override their own best interests.
    1. The business had a policy that you should report safety incidents when you see them. The process around that was you fill out a form and fax it to a number and someone will take action on it. The safety manager in this company saw that and decided to digitize this workflow and optimize it. Once this process was put into place, the number of safety incidents reported increased 5 times. The speed at which safety incidents were addressed increased by 60%.
  39. Jan 2020
  40. Dec 2019
  41. Nov 2019
    1. Epiphany aims to present the simplest interface possible for a browser. Simple does not necessarily mean less-powerful. The commonly-used browsers of today are too big, buggy, and bloated. Epiphany is a small browser designed for the web: not for mail, newsgroups, file management, instant messaging, or coffeemaking. The UNIX philosophy is to design small tools that do one thing and do it well.
  42. Sep 2019
  43. Oct 2018