1,095 Matching Annotations
  1. Aug 2021
    1. In everyday usage, MST is often referred to as Mountain Time (MT) or the Mountain Time Zone. This can add a bit of confusion as the term Mountain Time does not differentiate between standard time and Daylight Saving Time, so Mountain Time switches between MST and MDT in areas that use DST during part of the year.
    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.
    1. The Simplified Spelling Board of the early 1900s in the United States made gauge one of its targets in the early 1920s, urging the replacing of au with a to yield gage. From Simplified Spelling Board, Handbook of Simplified Spelling (1920): Principles Adopted Its [the Board's] recommendations, accordingly, have been based on the following principles : 1) When current usage offers a choice of spellings, to adopt the shortest and simplest. EXAMPLES : blest, not blessed ; catalog, not catalogue; center, not centre; check, not cheque or checque; gage, not gauge; gram, not gramme; honor, not honour; license, not licence; maneuver, not manoeuvre; mold, not mould; plow, not plough; quartet, not quartette; rime, not rhyme; tho, not though; traveler, not traveller.
    2. What happens when you look it up in a dictionary rather than as a phrase in Google? Google just catalogues other people's [mis-]uses
  2. Jul 2021
    1. For user-contributed data that's freeform and unstructured, use jsonb. It should perform as well as hstore, but it's more flexible and easier to work with.
    1. So long as the filters are only using GET requests to pull down links, there’s nothing fundamentally wrong with them. It’s a basic (though oft-ignored) tenet of web development that GET requests should be idempotent; that is, they shouldn’t somehow change anything important on the server. That’s what POST is for. A lot of people ignore this for convenience’s sake, but this is just one way that you can get bitten. Anyone remember the Google Web Accelerator that came out a while ago, then promptly disappeared? It’d pre-fetch links on a page to speed up things if you clicked them later on. And if one of those links happened to delete something from a blog, or log you out… well, then you begin to see why GET shouldn’t change things. So yes, the perfect solution to this is a 2-step unsubscribe link: the first step takes to you a page with a form on it, and that form then POSTs something back that finalizes the unsubscribe request.
    2. Two step unsubscribe, where the link in the email goes to a webpage with a prominent “click here to unsubscribe” button is often a good thing for unsubscription. It also gives people an option to not unsubscribe, when they click on the wrong link, or hit “return” with the wrong link focused, in a mail inadvertently, which isn’t that unusual in link-laden emails.
  3. test-prof.evilmartians.io test-prof.evilmartians.io
    1. That's it! Just replace let! with let_it_be. That's equal to the before_all approach but requires less refactoring.
    2. That technique works pretty good but requires us to use instance variables and define everything at once. Thus it's not easy to refactor existing tests which use let/let! instead.
    1. Looking deeper, you can see a large amount of issues open, bugs taking months to fix, and pull requests never seem to be merged from outside contributors. Apollo seems unfocused on building the great client package the community wants.
    2. This sort of behaviour indicates to me that Apollo is using open-source merely for marketing and not to make their product better. The company wants you to get familiar with Apollo Client and then buy into their products, not truly open-source software in my opinion. This is one of the negatives of the open-core business model.
    1. It’s fun but when would we ever use things like this in actual code?When it’s well tested, commented, documented, and becomes an understood idiom of your code base.We focus so much on black magic and avoiding it that we rarely have a chance to enjoy any of the benefits. When used responsibly and when necessary, it gives a lot of power and expressiveness.
    1. Give the same task to a junior developer, and they might code it faster because they do not think twice while reading a requirement. Their approach is more like converting English to Java (or whatever programming language they use).

      Indeed, not only younger programmers are thinking faster, they have much less mental burden when programming.

  4. Jun 2021
    1. Personally, I like having Redis as a dependency as most of my current applications use two Redis instances; persistent store and volatile.
    1. I've seen (and fixed) Ruby code that needed to be refactored for the client objects to use the accessor rather than the underlying mechanism, even though instance variables aren't directly visible. The underlying mechanism isn't always an instance variable - it can be delegations to or manipulations of a class you're hiding behind a facade, or a session store with a particular format, or all kinds. And it can change. 'Self-encapsulation' can help if you need to swap a technology, a library, an object specification, etc.
    2. Also, Sandi Metz mentions this in POODR. As I recall, she also advocates wrapping bare instance variables in methods, even when they're only used internally. It helps avoid mad refactoring later.
    3. But sure, go ahead and enforce self-encapsulation if you like; it makes it easier to do memoization or whatever later on.
    1. Programmers should be encouraged to understand what is correct, why it is correct, and then propagate.

      new tag?:

      • understand why it is correct
    2. Thanks, this was just what I was looking for! This is a perfect appropriate use of instance_eval. I do not understand the nay-sayers. If you already have your array in a variable, then sure, a.reduce(:+) / a.size.to_f is pretty reasonable. But if you want to "in line" find the mean of an array literal or an array that is returned from a function/expression — without duplicating the entire expression ([0,4,8].reduce(:+) / [0,4,8].length.to_f, for example, is abhorrent) or being required to assign to a local, then instance_eval option is a beautiful, elegant, idiomatic solution!!
    1. If you do it really right, you’ll find yourself following, not leading because the team culture gets bigger than any one person.

      A really good leader, becomes obsolete.fr

    1. Another problem was the ambiguity of RFC 3066 regarding the generative syntax. The idea of "language-dash-region" language tags was easy enough to grasp; most users didn't read RFC 3066 directly or consider the unstated-but-realized implication that other subtags might sometimes occur in the second position.

      unstated-but-realized

    1. Your attempt should work. There is a mismatch in column name in your query though. The query uses col2 but the table is defined with col1.

      I would actually lean towards making this a comment, at least the typo fix part. But if you remove the typo fix part, all that's left is "should work", which I guess should be a comment too since it's too short to be an answer.

  5. May 2021
    1. Because constants in Ruby aren't meant to be changed, Ruby discourages you from assigning to them in parts of code which might get executed more than once, such as inside methods.
    1. or simply install the package to devDependencies rather than dependencies, which will cause it to get bundled (and therefore compiled) with your app:
    1. MJML has been designed with responsiveness in mind. The abstraction it offers guarantee you to always be up-to-date with the industry practices and responsive. Email clients update their specs and requirements regularly, but we geek about that stuff - we’ll stay on top of it so you can spend less time reading up on latest email client updates and more time designing beautiful email.
  6. Apr 2021
    1. This is definitely not the place to report bugs related to sass, rails, or sprockets. Each project has it's own issue tracker (not on SO)
    1. can you remove the not a bug label considering that PaperTrail is creating this empty versions even when :updated_at is an ignored attribute?
    1. (Yes, I realize from a technical, end-user perspective this really doesn't matter.)

      The word "technical" in this sentence doesn't seem to belong or to clarify anything. I think it would be clearer without it.

      But I think I understand what he's saying, which is that technical details don't matter to the end user. They only know/see/care if it works or not.

    1. We are are continuing our commitment to creating our games that are free and widely accessible anyone that is curious by making our game files available under Creative Commons license BY–NC–SA 4.0. That means we will continue offering a full, free print-and-play kit for Pax Pamir, and later this campaign, John Company! Anyone can use, remix, and share the game, so long as they do not use it for commercial purposes. 
    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. The game is lame and the main gimmick of writing stuff is being shat on with the horrendous gameplay. If you have a very unique formula, don't try to change it.
    1. Although echo "$@" prints the arguments with spaces in between, that's due to echo: it prints its arguments with spaces as separators.

      due to echo adding the spaces, not due to the spaces already being present

      Tag: not so much:

      whose responsibility is it? but more: what handles this / where does it come from? (how exactly should I word it?)

    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!).
    1. This is a new version of the game and it's actually worse than the one I used to play as a child. Puzzles have been removed, pathfinding is buggier than I remember it to be and you can't aqcuire a specific item at the beginning of the game. It's definitely not worth buying, even for nostalgia's sake.
    1. I was almost immediately deflated. This is a cut-down reskin of a 3 year old game from the same company.
    1. Not really sure who the audience is... the puzzles are a bit too difficult for kids but won't tax adults very much at all--some bare bones hidden object, match-3 and peg hopping.
    1. I would love to ask devs what the ****. It used to be a not bad puzzler with crappy movement, but it had to be at least a bit interesting if my Steam counter shows 5 hours. Now it is a crap.There is nothing left from the previous version - except the fact that the main character is a robot. Earlier the game looked like a bad retro, and now it looks like sweet flood. The robot moves extremely slowly now and, what's worse, it seems that it has the same levels as a game that used to be called "Abrix for kids".Achievements were reset and the new ones are broken, so it is enough to make a step to achieve 1000 steps, move a block one to get a 1000 moved blocks achievement and same with destroying blocks. I think it is even better this way. No one has to play it more than few minutes.It is sad what happened with Abrix. Avoid it.
    1. Ultimately, Shelter Generations relies on your capacity to dig into its subtleties. On that overt level it's an obtuse and obviously indie game, and it's really quite demanding of the player; it asks them to figure their own way through the game, and it asks them to really commit to an emotional connection to these hopeless little cubs.
    1. Explicit affordances are obvious, perceptual features of an item that clue you in on how it is to be used. With explicit affordances, physical appearance and any accompanying language or text inform the user of how an object is to be used.
    2. Many designers strive to create products that are so easy to navigate, their users can flow through them at first glance. To design something with this level of intuitiveness, it’s imperative designers understand affordances—what they are and how to use them.
    1. We also include a large number of detailed picture examples, often with 3D renders, that help you understand the context of the rules. For these reason, we generally don't start laying out the final rulebook until production art is complete. Writing and laying out a 20 page rule book like this generally takes about 3 months from start to finish, usually requiring a complete rewrite or two, and involves dozens of editors.
    1. however, if this is relevant to just one spec, you don't necessarily need to include devise helpers to all your controllers specs, you can just explicitly include those helpers in that one controller describe block: require 'spec_helper' describe MyCoolController include Devise::TestHelpers it { } end
  7. Mar 2021
    1. Application: 3-D Shape RegistrationAn important problem in model-based recognition is to find the transformation of a set of datapoints that yields the best match of these points against a shape model. The process is oftenreferred to asdata registration. The data points are typically measured on a real object by rangesensors, touch sensors, etc., and given in Cartesian coordinates. The quality of a match is oftendescribed as the total squared distance from the data pointsto the model. When multiple shapemodels are possible, the one that results in the least total distance is then recognized as the shapeof the object.Quaternions are very effective in solving the above least-squares-based registration problem.
    2. ts geo-metric meaning is also more obvious as the rotation axis and angle can be trivially recovered.
    1. Svelte is there when I need it with useful APIs, but fades into the background as I put my app together.
    2. but I like that Svelte comes with a good CSS story out the box.

      comes with a good CSS story out the box

    3. Svelte is different in that by default most of your code is only going to run once; a console.log('foo') line in a component will only run when that component is first rendered.
    1. With all this “monetization” happening around Trailblazer, we will also make sure that all free and paid parts of the project grow adult and maintan an LTS - or long-term support - status. Those are good news to all you users out there having been scared to use gems of this project, not knowing whether or not they’re being maintained, breaking code in the future or making your developers addicted to and then cutting off the supply chain. Trailblazer 2.1 onwards is LTS, and the last 1 ½ years of collaboration have proven that.
    1. seems a interesting talk on k8s

      听了一半,这里的 Builders and Operators 指的是运维而非 k8s controller 里的 operator,以后有机会再看看吧


      配合自己用 kubeadm 部署一个 cluster 可能不错

    1. If you want to compile youself you can pass the --with-features=huge to the configure script. Note, however, this does not enable the different language bindings because those are mostly optional and also the various GUIs need to enabled specifically, because you can have only one gui.

      This explains why the standard vim package on ubuntu doesn't have GUI support (I was going to say because it wouldn't know which GUI you needed, but I think it would based on the Ubuntu variant: GNOME, KDE, etc.) (maybe because it wouldn't know whether you wanted GUI support at all)

      I was going to say because it wouldn't know which GUI you needed, but I think it would based on the Ubuntu variant: GNOME, KDE, etc.

      found answer to that: https://hyp.is/NyJRxIgqEeuNmWuaScborw/askubuntu.com/questions/345593/how-to-build-vim-with-gui-option-from-sources

      so you have to install a different package with GUI support, like vim-gtk or vim-athena

    1. Very often in these monorepos, packages are so incredibly specific in functionality, the question then becomes why even have a separate package at all if it’s tightly coupled? Can you use these packages independently or are they tied to specific versions of other packages in the monorepo? It’ll probably be easier to remove the mask and just work as a monolith.
    1. The number one problem that I see developers have when practicing test-first development that impedes them from refactoring their code is that they over-specify behavior in their tests. This leads developers to write more tests than are needed, which can become a burden when refactoring code.
    1. much software requires continuous changes to meet new requirements and correct bugs, and re-engineering software each time a change is made is rarely practical.
    1. Microlibraries are easier to understand, develop and test. They make it easier for new people to get involved and contribute. They reduce the distinction between a “core module” and a “plugin”, and increase the pace of development in D3 features.
    2. Small files are nice, but modularity is also about making D3 more fun.
    1. Unfortunately, given how widely used concat_javascript_sources is, this required changing a lot of tests. It would be nice if we could remove some of the duplication in these tests (so that similar changes would not require updating this many tests), but that can come in another PR.
    1. I don't understand why this isn't being considered a bigger deal by maintainrs/the community. Don't most Rails developers use SCSS? It's included by default in a new Rails app. Along with sprockets 4. I am mystified how anyone is managing to debug CSS in Rails at all these days, that this issue is being ignored makes sprockets seem like abandonware to me, or makes me wonder if nobody else is using sprockets 4, or what!
    2. Meh... as I said earlier, I think using Webpack is the recommended way now. Another issue is there is no way to generate source maps in production.
    3. sprockets 4 makes Chrome browser identification of SCSS css lines _worse_
    4. But maybe few are still using sprockets at all, for JS or (S)CSS anymore? Hard to say.
    5. If I can't do something to change the sprockets 4 debugging experience I am seeing, I am going to probably downgrade back to sprockets 3. I am finding it impossible to develop CSS the ways I am used to.
    6. Is there a PR to... something? sassc-rails? That would make the patch not necessary? (I don't know if there's any good way to monkey-patch that in, I think you have to fork? So some change seems required...) Should the defaults be different somehow? This is very difficult to figure out.
    7. Is there a PR to... something? sassc-rails?
    1. Any updates on this one? It makes debugging JS and CSS in the web inspector next to impossible when you can't get any help finding the offending code in your own source files.
    1. Want to know how to build a taxi app that will become the next Uber or Carb? It is a reasonable question considering how convenient and cost-effective it is to use a taxi instead of maintaining your own vehicle. The best way for a cab company to ensure this convenience for customers is to build a taxi booking app.
    1. The HTML5 form validation techniques in this post only work on the front end. Someone could turn off JavaScript and still submit jank data to a form with the tightest JS form validation.To be clear, you should still do validation on the server.
    1. Therefore client side validation should always be treated as a progressive enhancement to the user experience; all forms should be usable even if client side validation is not present.
    2. It's important to remember that even with these new APIs client side validation does not remove the need for server side validation. Malicious users can easily workaround any client side constraints, and, HTTP requests don't have to originate from a browser.
    3. Since you have to have server side validation anyways, if you simply have your server side code return reasonable error messages and display them to the end user you have a built in fallback for browsers that don't support any form of client side validation.
  8. 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...

    1. Ci taatu guy googu la jigéeni Ajoor yi di jaaye sanqal.

      C'est sous ce baobab que les femmes originaires du Kayor vendent de la semoule de mil.

      ci -- close; at @, in, on, inside, to.

      taat+u (taat) wi -- base, bottom, foundation, buttocks.

      guy gi -- baobab. 🌴

      googu -- that (closeness).

      la -- (?).

      jigéen+i (jigéen) bi ji -- sister versus brother; woman as opposed to man. 👩🏽

      ajoor bi -- person from Kayor.

      yi -- the (plural).

      di -- be; mark of the imperfective affirmative not inactual.

      jaay+e (jaay) v. -- sell.

      sanqal si -- millet semolina. 🌾

    2. Peñe, kenn du ko able.

      Un peigne, personne ne le prête.

      peñe bi -- (French) comb.

      kenn -- no one.

      du -- to be (negative). ➖

      ko -- it.

      able v. -- to lend.

    3. Sëriñ boobu aj na daaw, doomam a ko wuutu léegi.

      Ce marabout est décédé l'an dernier, c'est son fils qui le remplace maintenant.

      sëriñ bi -- marabout.

      boobu -- this.

      aj (Arabic: Hajj) v. -- make the pilgrimage to Mecca. 🕋; deceased ☠️ (for a religious personality).

      na -- he (?).

      daaw n. -- last year. 🗓

      doom+am (doom) ji -- child by descent 👶🏽; doll🪆; to have a child.

  9. Feb 2021
    1. Do you have collaborators who could have generated keys and sold them on their own? DIG's Steam keys and other stores' Steam keys must have some source, after all. Keys don't generate themselves, and only your accounts should be able to request them.This particular game was in Bunch Keys Indie Wizardry Bundle. I assume you had a proper contract for that. Maybe DIG or an intermediary bought 50-200 copies of it?
    2. It isn't stealing because you or an associate must have generated and given them the keys in some way or another?Ideally you would ask a DIG bundle buyer to show you their key for your game, so you can figure out what key request batch it came from, and then you can scratch your head and wonder who you gave those keys to and what journey they took afterwards.
    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. Personally, I'm starting to think that the feature where it automatically adds xray.js to the document is more trouble than it's worth. I propose that we remove that automatic feature and just make it part of the install instructions that you need to add this line to your template/layout: <%= javascript_include_tag 'xray', nonce: true if Rails.env.development? %>
    1. now that I realize how easy it is to just manually include this in my app: <%= javascript_include_tag 'xray', nonce: true if Rails.env.development? %> I regret even wasting my time getting it to automatically look for and add a nonce to the auto-injected xray.js script
    2. This is failing CI because CI is testing against Rails < 6. I think the appropriate next steps are: Open a separate PR to add Rails 6 to the CI matrix Update this PR to only run CSP-related test code for Rails >= 6.0.0 Can you help with either or both of those?
    1. At work, we often mention "throwing something over the fence" and "wrong rock" so there is (to us) a proverbial fence and a proverbial wrong rock.
    1. Keep in mind that third party code with references to other files also processed by the asset Pipeline (images, stylesheets, etc.), will need to be rewritten to use helpers like asset_path.
    1. found that using only the Pascal-provided control structures, the correct solution was given by only 20% of the subjects, while no subject wrote incorrect code for this problem if allowed to write a return from the middle of a loop.
    2. computers theoretically need only one machine instruction (subtract one number from another and branch if the result is negative)
    1. This is a useful approach to error handling, but please don’t take it to extremes! See my post on “Against Railway-Oriented Programming”.
    1. provide interfaces so you don’t have to think about them

      Question to myself: Is not having to think about it actually a good goal to have? Is it at odds with making intentional/well-considered decisions?  Obviously there are still many of interesting decisions to make even when using a framework that provides conventions and standardization and makes some decisions for you...

    1. What this means is: I better refrain from writing a new book and we rather focus on more and better docs.

      I'm glad. I didn't like that the book (which is essentially a form of documentation/tutorial) was proprietary.

      I think it's better to make documentation and tutorials be community-driven free content

    2. The new 2.1 version comes with a few necessary but reasonable changes in method signatures. As painful as that might sound to your Rails-spoiled ears, we preferred to fix design mistakes now before dragging them on forever.
    3. The new call API is much more consistent and takes away another thing we kept explaining to new users - an indicator for a flawed API.
    4. Also, the more I use Trailblazer in projects or even in Trailblazer itself, I feel how needed those new abstractions are.
    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.
    1. compose(Add, x: x, y: 3)

      How is this better than simply:

      Add.run(x: x, y: 3)
      

      ?

      I guess if we did that we would also have to remember to handle merging errors from that outcome into self...

    2. Why is all this interaction code better? Two reasons: One, you can reuse the FindAccount interaction in other places, like your API controller or a Resque task. And two, if you want to change how accounts are found, you only have to change one place.

      Pretty weak arguments though...

      1. We could just as easily used a plain object or module to extract this for easy reuse and having it in only one place (avoiding duplication).
    3. For this one we'll define a helper method to handle raising the correct errors. We have to do this because calling .run! would raise an ActiveInteraction::InvalidInteractionError instead of an ActiveRecord::RecordNotFound. That means Rails would render a 500 instead of a 404.

      True, but why couldn't it handle this for us?

    1. No one has requested it before so it's certainly not something we're planning to add.
    2. I'm sure there will be a few other people out there who eventually want something like this, since Interactions are actually a great fit for enforcing consistency in data structures when working with a schemaless NoSQL store, but obviously it's still a bit of a niche audience.
    3. To give a little more context, structures like this often come up in my work when dealing with NoSQL datastores, especially ones that rely heavily on JSON, like Firebase, where a records unique ID isn't part of the record itself, just a key that points to it. I think most Ruby/Rails projects tend towards use cases where these sort of datastores aren't appropriate/necessary, so it makes sense that this wouldn't come up as quickly as other structures.
    1. Consequently, you act irresponsibly when you adopt any programming practice simply because "that's the way you're supposed to do things."
    2. My point is that you should not program blindly. You must understand the havoc a feature or idiom can wreak. In doing so, you're in a much better position to decide whether you should use that feature or idiom. Your choices should be both informed and pragmatic.
    3. And just because a feature or idiom is commonly used does not mean you should use it either.