We would also like it if breaking changes were not made in a minor version update. If this breaking change is absolutely necessary, it should be made with TypeScript version 4.x, not in a minor version update. It's very notable that according to Dependabot, this version update saw an over 10% failure rate, despite being a minor update, when most other builds have less than 3%. Heck, even the 2.9.2 → 3.0.1 breaking change had a lower rate of failure than this one! Surely Microsoft can not consider that acceptable.
- Aug 2021
-
github.com github.com
-
-
github.com github.com
-
which seems to resolve the issue for me and makes no casts, ensuring that Typescript can keep doing its good job of widening as much as necessary and narrowing as much as possible without me having to claim I know better than the compiler. I'm posting it here since it doesn't seem to have been mentioned anywhere.
makes no casts, ensuring that Typescript can keep doing its good job of widening as much as necessary and narrowing as much as possible without me having to claim I know better than the compiler.
-
I'd like to update my proposal to be more general, following your answer on Stack Overflow and hack mentioned at the top of #14520
-
I'd like to think this issue isn't quite a duplicate
-
The problem is that, with the literal types, the includes call now gives a type error: // Error: Argument of type number is not assignable to 1 | 2 | 3 if(!legalValues.includes(userValue)) { throw new Error("..."); }
-
I think a more natural/appropriate behavior for type signature of includes would be for the literal types to be widened.
-
The above works great. However, the problem comes when I want to use literal types for my legal values. In my code, I want to do that so I can make sure I define a "handler" for every legal value: const legalValues = <const>["a", "b", "c"]; // later on... // Because legalValues entries are literal types, // I get a compiler error if I forget to define any behaviors const behaviors: { [K in typeof legalValues[number]]: any } = { a: something, b: somethingElse, c: anotherThing };
-
-
-
This isn't too restrictive, and provides a nice type type guard.
-
function includes<T, U extends T>(arr: readonly U[], elem: T): elem is U { return arr.includes(elem as any); }
-
Some details of my example were originally poorly chosen i.e. the example was constructed in a way that developer would probably have done a null check rather than a typeof comparison. I've addressed that now. My apologies to anyone who read this before-hand and thought the example seemed a bit too "fabricated".
-
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.
-
Changing every built-in function to accept anys would also "break" no one, but that doesn't make it a good idea. Part of TypeScript's value proposition is to catch errors; failing to catch an error is a reduction in that value and is something we have to weigh carefully against "Well maybe I meant that" cases.
-
Please read https://stackoverflow.com/questions/41750390/what-does-all-legal-javascript-is-legal-typescript-mean
-
See #14520 for discussion of upper-bounded generics.
Tags
- poorly chosen
- developer's intention
- javascript
- finding the right balance
- TypeScript: generics: upper-bounded
- TypeScript: generics
- getting in the way
- safety (programming)
- compromise
- poor example
- intention
- caveat
- contrived/toy example
- TypeScript: cost of using (tax)
- making it too easy to do the wrong thing
- relationship between
- TypeScript: type guards
- convenience
- TypeScript
- making it easy to do the right thing
Annotators
URL
-
-
stackoverflow.com stackoverflow.com
-
This could be achieved using a dummy validating function. const validateType = <T> (obj:T) => undefined
-
-
github.com github.com
-
I believe he wants to use the as const feature while still type checking that the structure matches an interface. A workaround I'd use for something like that would be interface ITest { a: number; b: string; } let foo = { a: 5, b: "Hello" } as const;
-
<ITest>foo; //a useless javascript line, but checks the var `foo` is assignable to `ITest`
-
-
stackoverflow.com stackoverflow.com
-
the tuple() function you need can be succinctly written as: export type Lit = string | number | boolean | undefined | null | void | {}; export const tuple = <T extends Lit[]>(...args: T) => args;
-
const list = ['a', 'b', 'c'] as const; // TS3.4 syntax type NeededUnionType = typeof list[number]; // 'a'|'b'|'c';
-
This will obviate the need for a helper function of any kind.
-
This type of assertion causes the compiler to infer the narrowest type possible for a value, including making everything readonly.
"infer"?
-
possible to tell the compiler to infer the type of a tuple of literals as a tuple of literals, instead of as, say, string[], by using the as const syntax.
-
This is annoying repetition, but at least it doesn't introduce an extraneous object at runtime.
-
Or, maybe better, interpret the list as a tuple type: const list: ['a','b','c'] = ['a','b','c']; // tuple
-
You can force the type system to remember each value as a literal string: const list = ['a' as 'a','b' as 'b','c' as 'c']; // infers as ('a'|'b'|'c')[]
-
One problem is the literal ['a','b','c'] will be inferred as type string[], so the type system will forget about the specific values.
-
t's not supposed to work with that, since by the time you do const xs = ['a','b','c'] the compiler has already widened xs to string[] and completely forgotten about the specific values.
Tags
- TypeScript: helper functions
- succinct
- TypeScript: narrow or widen
- workaround
- TypeScript: type system
- TypeScript: union
- concise
- hard-coded list of literals
- TypeScript: tuple type
- TypeScript
- duplication
- obviate
- better/superior solution/way to do something
- TypeScript: as const
- forcing (software)
- newer/better ways of doing things
Annotators
URL
-
-
github.com github.com
-
function strictIsDog<T extends Dog extends T ? unknown : never>( // like <T super Dog> candidate: Dog | T // if Dog extends T then Dog | T is T ): candidate is Dog { // compiler recognizes that Dog | T can narrow to T return "bark" in candidate; } if (strictIsDog(animal)) {} // okay if (strictIsDog(dog)) {} // okay if (strictIsDog(mixed)) {} // okay if (strictIsDog(cat)) {} // error! // ~~~ <-- Cat is not assignable to Dog
-
If you really want to prevent people from passing in known Cat instances to isDog() you can fake up a lower-bound type parameter constraint like this:
-
therefore in practice it's a bit academic to worry about which lines inside that block the compiler should be happy or unhappy about. From falsehood, anythihng follows. So the compiler is free to say "if the impossible happens, then X is an error" or "if the impossible happens, then X is not an error". Both are valid (although one might be more or less surprising to developers).
-
* Now it's correct within the laws of the type system, but makes zero practical sense, * because there exists no runtime representation of the type `Date & string`. * * The type system doesn't care whether a type can be represented in runtime though.
new tag?: makes zero practical sense
makes zero practical sense because there exists no runtime representation of the type
-
no plans to reduce empty cases to never more aggressively to help developers exclude weird/absurd/accidental cases
-
As a design decision, TypeScript does not collapse that type to `never` (although it could).
-
thank you again for taking the time to explain how the compiler thinks in such an elaborate way. This is some blog post material!
-
candidate is Dog { // compiler recognizes that Dog | T can narrow to T
-
What I don't understand is why you need to make it explicit? Given: function isBarAlsoFoo(obj: Bar): obj is Foo; Without resorting to any, how can we get any code to typecheck in which you pass an object that's not a Bar to isBarAlsoFoo()?
-
The Cat & Dog says meowoof?
-
I think I get why adding a seemingly neutral T is T bit actually changes a lot.
-
Please correct me if anything in there is incorrect!
-
I wrote down how I understand it using layman's terms for anyone finding this issue in the future.
-
that is, a type like {foo: never} does not itself get reduced to never even though you shouldn't be able to have a value of type {foo: never}
-
Using the second type guard forces the user to write a more precise type and therefore manifest any nonsensical type guards that produce never, like: function silly<T extends number>(candidate: T): candidate is T & boolean { … }
-
You can't just move 'side-ways' between unrelated types; you need to move either up or down the lattice.
-
There is always a way to work around that by doing expr as unknown as T, but it stops people making basic errors.
-
Search Terms:
Tags
- workaround
- correct me if I'm wrong
- TypeScript: reducing types
- footgun
- annotation meta: may need new tag
- surprising behavior
- in one's own words
- appreciation
- key point
- TypeScript: type system
- detailed answer
- I don't understand
- funny
- impossible
- in practice
- good point
- in theory
- detailed explanation
- academic
- good question
- TypeScript: type guards
- theory vs. practice
- TypeScript
- TypeScript: never
- make it hard to get wrong/incorrect
- providing list of search terms/keywords to make it easier to find later
- need simple explanation
- unintuitive
Annotators
URL
-
-
stackoverflow.com stackoverflow.com
-
The best way to do this is to derive the type Format from a value like an array which contains all of the Format literals.
-
That should work as expected and not be too verbose (or at least it doesn't repeat string literals anywhere)
-
So is @Ryan Cavanaugh's answer the only viable solution? It seems extremely verbose...
-
My question is specifically if there is a way to do user defined type guards using the type itself
-
-
stackoverflow.com stackoverflow.com
-
function isKeyOfMcuParams(x: string): x is keyof McuParams { switch (x) { case 'foo': case 'bar': case 'baz': return true; default: return false; } }
-
you can use whatever control flow block you like instead of return (e.g. an if, or throw, etc)
-
Ryan Cavanaugh
-
Is it possible to write a user defined type guard for a keyof string type such as keyOf foo when foo is defined ONLY as a type (and not in an array)?
-
-
charlypoly.com charlypoly.com
-
While this io-ts might look “overkill”, if you’re dealing with data or complex SPA, you might want to make your types “real” and io-ts is the best way to reach this.
-
Introduced in the perfectly named “Typescript and validations at runtime boundaries” article @lorefnon, io-ts is an active library that aim to solve the same problem as Spicery:TypeScript compatible runtime type system for IO decoding/encoding
io-ts
-
[K in keyof User]-?:
-
It means that when having a type guard:TypeScript and JavaScript runtime are tied to the same behaviour.
-
Inside the if statement, TypeScript will assume that amount cannot be anything else than a string, which is true also at the runtime thanks to typeof JavaScript operator.
-
This “gap” between what we call “runtime” and “static analysis” can be filled using TypeScript Type Guards.
-
We will see that this is not a fatality, because TypeScript is more powerful than you thought and some developers of the community are very crafty.
-
TypeScript is often resumed as “only being a static type checker”, meaning that, at runtime, all the gains of types are a loss.In this chapter, we will see together that this allegation is totally untrue.
-
-
dev.to dev.to
-
we use a type guard here to say that, if this function returns true, any further usage of key will be of the specified type. Otherwise, it's still just a string.
-
keyof is a keyword in TypeScript which accepts a given object type and returns a union type of its keys. These are equivalent: type StatusKey = keyof { online: string; offline: string; busy: string; dnd: string; } type StatusKey = 'online' | 'offline' | 'busy' | 'dnd'
-
function hasKey<O>(obj: O, key: PropertyKey): key is keyof O { return key in obj }
-
which looks like complete nonsense if you don't really know what's going on
-
-
stackoverflow.com stackoverflow.com
-
Adding to the accepted answer, if you happen to need to use a type guard against a mixin, you'll get this error too, since the is operator doesn't behave as an implements would.
-
Regarding the error message, the predicate type must be assignable to the value type because the type guard is used to check whether a value with a less-specific type is in fact a value with a more-specific type. For example, consider this guard: function isApe(value: Animal): value is Ape { return /* ... */ } Ape is assignable to Animal, but not vice versa.
-
If you really don't want to use any, you could use an empty interface - {} - instead:
-
If there is no relationship between the value's type and the type in the type predicate, the guard would make no sense. For example, TypeScript won't allow a user-defined guard like this: function isString(value: Date): value is string { return typeof value === "string"; }
-
the generic means "give me one of each function a -> Boolean" so if any of those functions doesn't exist, then the generic doesn't exist.
-
-
stackoverflow.com stackoverflow.com
-
const isValidMethodForHandler = <T extends { [i: string]: any }>(handler: T) => ( method: string ): method is Extract<keyof T, string> => Object.keys(handler).indexOf(method) !== -1;
-
-
blog.alexdevero.com blog.alexdevero.com
-
Aside to global and local scope there is also something one could call a “block” scope. This is not an “official” type of scope, but it does exist. Block scope was introduced to JavaScript as a part of the ES6 specification. It was introduced along with two new types of variables let and const.
-
-
en.wikipedia.org en.wikipedia.org
-
github.com github.com
-
Why not just prettier-ignore? Because I want to keep Prettier here. Still format my code. But just with another config. This already works with prettierrc > overrides. But this proposal is for a better usability and flexibility.
-
-
github.com github.com
-
In the vast majority of cases when I'm using prettier-ignore I'm only really looking to prevent it from breaking my code into new lines, whilst keeping its other transformations such as switching quotes and adding space between brackets. When ignoring single lines, fixing these formatting problems by hand is very manageable. With the ability to have Prettier ignore entire blocks of code I think the ability to specify what you want it to ignore is essential.
-
This should be basic functionality.
-
Noticed that with 100+ s, I am not alone here. There are definitely a lot of devs wanting this feature. So I took some time out and decided to give this a go myself. I have created a PR for the same
-
In javascript prettier-ignore ignores the next block, so what I did was just make the next few lines a block.
-
I will start working on this feature if there are at least 100 thumbs up on this comment. Let's see if people still need this feature except myself.
Tags
- good point
- workaround
- gauging interest
- programming: block (of code: {}, begin/end)
- configuration: overriding/disabling some things without having to override/disable _all_ of them (flexibility)
- don't just complain: do something about it
- don't just complain; help improve/fix things
- expected library/language to have feature but is missing
- I agree
- prettier
Annotators
URL
-
-
english.stackexchange.com english.stackexchange.com
-
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.
-
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
-
-
github.com github.com
-
Using a flag to disable prettier for a line, the next line or until I activate it again (ESLint like syntax). // prettier-disable border: { sep: "║", topLeft: "╔", topMid: "╦", top: "═", topRight: "╗", midLeft: "╠", midMid: "╬", mid: "═", midRight: "╣", botLeft: "╚", botMid: "╩", bot: "═", botRight: "╝" }, // prettier-enable
-
-
developer.mozilla.org developer.mozilla.orgwith2
-
If you forget to define x in the object you pass as the second argument, or if there's some similar bug or confusion, you won't get an error -- just unexpected results.
-
Performance pro & contra
-
-
github.com github.com
-
In general it should probably look something like: setClient(writable(apolloClient)); let client getClient().subscribe((_client) => client = _client);
.
-
-
stackoverflow.com stackoverflow.com
-
You should realize that a Svelte store is actually a very simple construct. It has a subscribe method, an optional set method and basically, that's all. Read the store contract in the docs: everything is in there. Three short rules. That means you can easily handle them (and create new sorts), because you know everything there is to know already!
you can do it!
-
-
medium.com medium.com
-
arguments = method_proc.parameters.map(&:last)
Gets names of parameters, like
[:arg_a, :b]Should be called
parameter_names(the key word being names). "arguments" implies that it is the actual values that were passed in — not the name of the variables to which they will be assigned. -
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.
-
What if I told you there was a way to do this in Ruby?:destructure def adds(a: 1, b: 2) a + bendadds(a: 1, b: 2)# => 3adds(OpenStruct.new(a: 1, b: 2))# => 3Foo = Struct.new(:a, :b)adds(Foo.new(1,2))# => 3
-
def destructure(method_name) meta_klass = class << self; self end method_proc = method(method_name) unless method_proc.parameters.all? { |t, _| t == :key } raise "Only works with keyword arguments" end arguments = method_proc.parameters.map(&:last) destructure_proc = -> object { values = if object.is_a?(Hash) object else arguments.map { |a| [a, object.public_send(a)] }.to_h end method_proc.call(values) } meta_klass.send(:define_method, method_name, destructure_proc) method_nameend
-
-
www.geeksforgeeks.org www.geeksforgeeks.org
-
Type Annotations:These annotations can be applied to any place where a type is being used. For example, we can annotate the return type of a method.
Tags
Annotators
URL
-
-
www.martinfowler.com www.martinfowler.com
-
this kind of run-time code generation is certainly more natural in Ruby, it's one of its Lispish elements
-
Rubyists don't call these things annotations. One of the things I like doing is to find common techniques that cross languages, for me this is a common technique and 'annotation' seems like a good generic word for it. I don't know if Rubyists will agree.
-
-
www.martinfowler.com www.martinfowler.com
-
Languages may provide annotations in ways that don't reflect the syntax of the language
-
When writing about programming, I prefer to use 'annotation' as the general term. Although .NET was first, the word 'attribute' is just too widely used for different things.
-
An annotation on a program element (commonly a class, method, or field) is a piece of meta-data added to that program element which can be used to embellish that element with extra code.
-
-
-
martinfowler.com martinfowler.com
-
I'm often asked to give talks at conferences, from which I've inferred that I'm a pretty good speaker - which is ironic since I really hate giving talks.
-
've long been a fan of board games, I enjoy a game that fully occupies my mind, clearing out all the serious thoughts for a bit, while enjoying the company of good friends. Modern board games saw dramatic improvement in the 1990's with the rise of Eurogames, and I expect many people would be surprised if they haven't tried any of this new generation.
Tags
Annotators
URL
-
-
www.martinfowler.com www.martinfowler.com
-
As with any classification there's a fuzzy line between them (Rake could be thought of either way.)
-
When people talk about internal DSLs I see two styles: internal minilanguages and language enhancements.
-
An internal DSL (often called an Embedded DSL) is a DomainSpecificLanguage that is written inside an existing host language. It's a common way of thinking in a number of programming language communities - particularly the Lisp community. It's now gaining a lot of attention as DSLs are a common way of thinking in the rapidly growing Ruby community.
-
-
-
# And standalone like a case:Qo.match(people.first, Qo.m(age: 10..19) { |person| "#{person.name} is a teen that's #{person.age} years old" }, Qo.m(:*) { |person| "#{person.name} is #{person.age} years old" })
-
# How about some "right-hand assignment" pattern matchingname_longer_than_three = -> person { person.name.size > 3 }people_with_truncated_names = people.map(&Qo.match_fn( Qo.m(name_longer_than_three) { |person| Person.new(person.name[0..2], person.age) }, Qo.m(:*) # Identity function, catch-all))
-
-
en.wikipedia.org en.wikipedia.org
-
Isolation ensures that concurrent execution of transactions leaves the database in the same state that would have been obtained if the transactions were executed sequentially
-
-
www.thespruce.com www.thespruce.com
-
Pipe assessment is never an elective activity. It's usually forced upon you when the toilets refuse to flush and wastewater comes up instead of going down.
-
-
softwareengineering.stackexchange.com softwareengineering.stackexchange.com
-
Someone could mean to say different thing by each of them, but there's hardly any common agreement.
-
the nomenclature seems to be totally confused
-
This is very useful answer to understand concepts behind each technical words.
-
-
Input check = Tests the user input, as opposed to some internal data structure or the output of a function.
-
which could also be a sanity check for a command like find or mail
input check could also be a sanity check
-
Special case check = Non-obvious, non-boundary special values, for example log(1 + the smallest floating point number).
-
logₑ-1 is iπ
-
Edge / Boundary check = The maximum or minimum input which is expected to produce correct output
.
-
Corner case check = A more complex boundary check (a corner is a two-dimensional boundary)
-
Sanity check = Does this even make sense? For example, if your application only outputs integers, sqrt(-1) and log(-1) are undefined.
-
Regardless of the differences between the words, what you'd use to describe a test depends on the semantics (meaning) of the test, not the exact code
-
-
softwareengineering.stackexchange.com softwareengineering.stackexchange.com
-
For better understanding of something that is complicated, just make it more simplier. In this example, just split the word into atoms, like these: Update - UP_DATE - make it up to date; Upgrade - UP_GRADE - move it to the upper (or next) grade (or level).
-
-
www.youtube.com www.youtube.com
-
2021.01.24-2021.08.09
date/time formats
I used to use this format, too!
-
Tags
Annotators
URL
-
-
www.bobvila.com www.bobvila.com
-
Alternately, set out a few bowls of white vinegar, which also neutralize odor molecules.
-
To remove any lingering musty smell, try the old-fashioned yet effective remedy of setting out a few small bowls of baking soda around the room; baking soda absorbs and neutralizes odor molecules well.
-
-
www.waterdamageplus.com www.waterdamageplus.com
-
Treat the carpet with a white vinegar spray. One part vinegar to two parts warm water. A simple spray over the carpet will remove any light surface residue – definitely better suited for a lesser spill or odor.
Tags
Annotators
URL
-
-
en.wikipedia.org en.wikipedia.org
-
usually-17-key section
hyhenation
-
-
www.merriam-webster.com www.merriam-webster.com
-
measuring the distance between datum points
-
to pick up a datum or two about geriatrics
-
an important historical datum
Tags
Annotators
URL
-
-
www.kickstarter.com www.kickstarter.com
-
Once a card has been played, any player can say “Mischief!” and call you on your potential lie
veggie alternative word
-
-
developer.mozilla.org developer.mozilla.org
-
However instead of using array.length for latter items; e.g. array[array.length-1] for the last item, you can call array.at(-1)
-
-
github.com github.com
-
You can add event modifiers with the on:click$preventDefault$capture={handler} syntax. If you use Svelte's native on:click|preventDefault={handler} syntax, it will not compile. You have to use "$" instead of "|". (The extra S inside the | stands for SMUI.)
How does it do that? I didn't think components could introspect to see which event handlers were added by the calling component?!
Does it actually somehow generate an event named something like
click$preventDefault$capture? I still don't get how that would work.
-
-
-
hover and resize window support #965 Closed Sorry, something went wrong. Collaborator jnicklas commented on Feb 25, 2013 Go, go @twalpole!
-
I have a rule that I won't allow Capybara to be monkey-patched in Poltergeist. This gives some indication to users about whether something is non-standard. So basically all non-standard stuff must be on page.driver rather than page (or a node).
-
What seems more problematic is divergence between drivers. For example, capybara-webkit and poltergeist support several of the same things. Let's take resizing the window as an example. In capybara-webkit this is page.driver.resize_window(x, y) and in poltergeist it's page.driver.resize(x, y). This means that if a user wants to switch from one to the other they have to change their code. Now I don't know if selenium does or doesn't support resizing the window, but supposing it doesn't I think there's still a lot of value in the capybara project deciding what the blessed API is, because then all the drivers that support that feature can implement it using the same API, increasing portability.
-
-
-
Provides empty Module#ruby2_keywords method, for the forward source-level compatibility against ruby2.7 and ruby3.
-
-
www.ruby-lang.org www.ruby-lang.org
-
Here is one of the most confusing cases: def foo(x, **kwargs) p [x, kwargs] end def bar(x=1, **kwargs) p [x, kwargs] end foo({}) #=> [{}, {}] bar({}) #=> [1, {}] bar({}, **{}) #=> expected: [{}, {}], actual: [1, {}]
-
The automatic conversion not only confuses people but also makes the method less extensible. See [Feature #14183] for more details about the reasons for the change in behavior, and why certain implementation choices were made.
-
3. The no-keyword-arguments syntax (**nil) is introduced You can use **nil in a method definition to explicitly mark the method accepts no keyword arguments. Calling such methods with keyword arguments will result in an ArgumentError. (This is actually a new feature, not an incompatibility)
-
This is useful to make it explicit that the method does not accept keyword arguments. Otherwise, the keywords are absorbed in the rest argument in the above example.
-
If you extend a method to accept keyword arguments, the method may have incompatibility as follows: # If a method accepts rest argument and no `**nil` def foo(*args) p args end # Passing keywords are converted to a Hash object (even in Ruby 3.0) foo(k: 1) #=> [{:k=>1}] # If the method is extended to accept a keyword def foo(*args, mode: false) p args end # The existing call may break foo(k: 1) #=> ArgumentError: unknown keyword k
-
There are three minor changes about keyword arguments in Ruby 2.7.
-
If your code doesn’t have to run on Ruby 2.6 or older, you may try the new style in Ruby 2.7. In almost all cases, it works. Note that, however, there are unfortunate corner cases as follows:
-
Ruby 2.6 or before themselves have tons of corner cases in keyword arguments.
-
You need to explicitly delegate keyword arguments. def foo(*args, **kwargs, &block) target(*args, **kwargs, &block) end
-
ruby2_keywords might be removed in the future after Ruby 2.6 reaches end-of-life. At that point, we recommend to explicitly delegate keyword arguments
-
foo({}, **{}) #=> Ruby 2.7: [{}] (You can pass {} by explicitly passing "no" keywords)
-
you can use the new delegation syntax (...) that is introduced in Ruby 2.7. def foo(...) target(...) end
-
-
ruby2_keywords allows you to run the old style even in Ruby 2.7 and 3.0.
-
In Ruby 2, you can write a delegation method by accepting a *rest argument and a &block argument, and passing the two to the target method. In this behavior, the keyword arguments are also implicitly handled by the automatic conversion between positional and keyword arguments.
-
Will my code break on Ruby 2.7? A short answer is “maybe not”. The changes in Ruby 2.7 are designed as a migration path towards 3.0. While in principle, Ruby 2.7 only warns against behaviors that will change in Ruby 3, it includes some incompatible changes we consider to be minor. See the “Other minor changes” section for details. Except for the warnings and minor changes, Ruby 2.7 attempts to keep the compatibility with Ruby 2.6. So, your code will probably work on Ruby 2.7, though it may emit warnings. And by running it on Ruby 2.7, you can check if your code is ready for Ruby 3.0.
-
If you want to disable the deprecation warnings, please use a command-line argument -W:no-deprecated or add Warning[:deprecated] = false to your code.
-
However, this style is not recommended in new code, unless you are often passing a Hash as a positional argument, and are also using keyword arguments
Tags
- incompatible
- workaround
- cross-linking so readers can get the full context
- Ruby 3
- upgrade path
- good example
- backwards compatible
- argument delegation
- changes (software)
- too much magic
- not:
- being explicit
- good explanation
- good/preferred/recommended behavior
- ruby: ArgumentError
- too automatic
- edge cases
- optional parameters
- Ruby
- newer/better ways of doing things
- package/tool to help with transition
- deprecation warnings
- cross-linking to issue
- ruby: keyword arguments
- unfortunate
- new feature
- confusing
- rationale for implementation choices
Annotators
URL
-
-
store.steampowered.com store.steampowered.com
-
In line with dishonest asset flippers, this has a number of fake positive reviews from compromised accounts, all in the same broken English.
-
Dungless is another GameMaker Studio asset flip from serial copy+paste infringers, Imperium Game. All these guys do is rip off game templates and projects from the Yoyogames/GameMaker Studio store and try to scam people into paying for someone else's work on Steam.This time they've ripped off a basic template for a 2D retro pixel platformer/brawler. In line with this asset flipping behaviour, the game was dumped immediately at launch into DailyIndieGame shovelware bundles.In line with dishonest asset flippers, this has a number of fake positive reviews from compromised accounts, all in the same broken English. Even if this wasn't just an asset flip, it would be garbage. Impossible to recommend.
-
-
store.steampowered.com store.steampowered.com
-
Developers leave in glaring issues that should have been resolved in the base game. For example, the original development had fuel, then scrapped it, then 3 or 4 years later they realize that logistics is actually important.The monetization scheme is inherently predatory. Charge your customers for a game that without DLC is without a backbone.
-
it shows history well, along with a good display of alternate history!
-
This is somehow the only game where you can play as an anti-fascist faction in Nazi Germany, drive the Nazis into the ocean, kill Hitler and reclaim Germany as a democracy, and that's somehow the most boring possible outcome.
-
-
api.rubyonrails.org api.rubyonrails.org
Tags
Annotators
URL
-
-
developer.mozilla.org developer.mozilla.org
-
Intl.DateTimeFormat().resolvedOptions().timeZone
-
-
momentjs.com momentjs.com
-
-
blog.logrocket.com blog.logrocket.com
-
Before you go like “Wow!!!”, understand that the packages highlighted above take a lot into consideration when detecting timezones. This makes them slightly more accurate than Intl API alone.
What exactly does moment do for us, then, that
TimeFormat().resolvedOptions().timeZone;doesn't do? Name one example where it is more accurate.
-
Intl.DateTimeFormat().resolvedOptions().timeZone
-
Don’t hate me, but let’s face it, if I showed you this, you may have ignored the rest of this article lol.
.
-
- Jul 2021
-
itsfoss.com itsfoss.com
-
Some applications mentioned here are not open source. They are listed here because they are available on Linux and the article’s focus is on Linux. Such applications are duly marked non-FOSS so that you can make a decision yourself.
Tags
Annotators
URL
-
-
-
function omit(obj, ...props) { const result = { ...obj }; props.forEach(function(prop) { delete result[prop]; }); return result; }
-
-
www.amitmerchant.com www.amitmerchant.com
-
You can use computed properties along with the omit keyword in this case like so. const varName = 'name'; const { [varName]:omit, ...updatedUser } = user;
first sighting: omit keyword
Or should that be "omitted"? https://hyp.is/lmYWKvAcEeurHLvjfrKYrw/stackoverflow.com/questions/43011742/how-to-omit-specific-properties-from-an-object-in-javascript
-
-
stackoverflow.com stackoverflow.com
-
function omit(key, obj) { const { [key]: omitted, ...rest } = obj; return rest; }
omitted
-
"modern environments" meaning if you're shipping un-transpiled code, this will work on 93% of browsers. See full compatibility at caniuse.com/…
-
-
deveiate.org deveiate.org
-
"balance".en.synset( :verb )
-
-
deveiate.org deveiate.org
-
If you prefer monkeypatching (around 70) linguistics methods directly onto core classes, you can do that by adding a 'monkeypatch' option to ::use:
-
-
stackoverflow.com stackoverflow.com
-
that's why I bolded "same column" with the or query. I can delete the comment altogether, but thought it would be helpful for people perusing "or" query SO questions.
-
Arel is a public API, or more precisely, it exposes one. Active Record just provides convenience methods that use it under the hood, It's completely valid to use it on it's own. It follows semantic versioning, so unless you are changing major versions (3.x.x => 4.x.x), there is no need to worry about breaking changes.
-
-
direnv.net direnv.net
-
A semantic command dispatch intended for loading external dependencies into the environment.
Tags
Annotators
URL
-
-
direnv.net direnv.net
-
direnv is not loading the .envrc into the current shell. It’s creating a new bash sub-process to load the stdlib, direnvrc and .envrc, and only exports the environment diff back to the original shell. This allows direnv to record the environment changes accurately and also work with all sorts of shells. It also means that aliases and functions are not exportable right now.
-
-
Tags
Annotators
URL
-
-
github.com github.com
-
To cache the result of calling use guix
-
Normally use guix can be frustratingly slow to use.
Tags
Annotators
URL
-
-
github.com github.com
-
and friends
Tags
Annotators
URL
-
-
-
-
direnv would have to do too many releases to keep up with all the other project changes
-
-
github.com github.com
-
Add this to ~/.direnvrc:
This is almost the same as used by
https://github.com/apollographql/apollo-server/blob/main/.envrc
except they (like I) prefer to just put it in local .envrc instead of requesting all developers put something in a file outside of the project root.
Also, the version at https://github.com/apollographql/apollo-server/blob/main/.envrc is slightly better.
Tags
Annotators
URL
-
-
-
watch_file .nvmrc local NVM_PATH="$HOME/.nvm/nvm.sh" if ! [ -f "$NVM_PATH" ]; then echo "Installing NVM" >&2 curl -o- https://raw.githubusercontent.com/creationix/nvm/master/install.sh | bash fi . "${NVM_PATH}" # `nvm use` will set up the environment to use some version matching what we have # in .nvmrc without talking to the network, assuming that there is any matching # version already downloaded. If there isn't (eg, you're just getting started, or # we just did a major version upgrade) then it will fail and `nvm install` will # download a matching version. nvm use || nvm install # Let you run npm-installed binaries without npx. layout node
-
-
github.com github.com
-
Auto-Detect & install BigCommerce's stencil-cli Auto-Detect & install Meteor Auto-Detect & install Shopify's themekit
Simpler option: https://github.com/apollographql/apollo-server/blob/main/.envrc
-
curl -o ~/.config/direnv/helpers.sh
-
-
github.com github.com
-
# This is a configuration file for direnv (https://direnv.net/), a tool that # allows you to automatically set up environment variables based on the current # directory. If you install and enable direnv, then this file will ensure that # `nvm` is installed in your home directory and that the version of Node in # .nvmrc is selected.
-
-
github.com github.com
-
Normative
-
-
There is currently no standard for transporting instances of JSON text within a stream protocol
-
-
datatracker.ietf.org datatracker.ietf.orgrfc64556
-
Relationship to TCP and HTTP _This section is non-normative._ The WebSocket Protocol is an independent TCP-based protocol. Its only relationship to HTTP is that its handshake is interpreted by HTTP servers as an Upgrade request. By default, the WebSocket Protocol uses port 80 for regular WebSocket connections and port 443 for WebSocket connections tunneled over Transport Layer Security (TLS) [RFC2818].
-
It is similarly intended to fail to establish a connection when data from other protocols, especially HTTP, is sent to a WebSocket server, for example, as might happen if an HTML "form" were submitted to a WebSocket server. This is primarily achieved by requiring that the server prove that it read the handshake, which it can only do if the handshake contains the appropriate parts, which can only be sent by a WebSocket client. In particular, at the time of writing of this specification, fields starting with |Sec-| cannot be set by an attacker from a web browser using only HTML and JavaScript APIs such as XMLHttpRequest [XMLHttpRequest].
-
The protocol is intended to be extensible; future versions will likely introduce additional concepts such as multiplexing.
-
The WebSocket Protocol is designed on the principle that there should be minimal framing (the only framing that exists is to make the protocol frame-based instead of stream-based and to support a distinction between Unicode text and binary frames). It is expected that metadata would be layered on top of WebSocket by the application Fette & Melnikov Standards Track [Page 9] RFC 6455 The WebSocket Protocol December 2011 layer, in the same way that metadata is layered on top of TCP by the application layer (e.g., HTTP). Conceptually, WebSocket is really just a layer on top of TCP that does the following: o adds a web origin-based security model for browsers o adds an addressing and protocol naming mechanism to support multiple services on one port and multiple host names on one IP address o layers a framing mechanism on top of TCP to get back to the IP packet mechanism that TCP is built on, but without length limits o includes an additional closing handshake in-band that is designed to work in the presence of proxies and other intermediaries Other than that, WebSocket adds nothing. Basically it is intended to be as close to just exposing raw TCP to script as possible given the constraints of the Web. It's also designed in such a way that its servers can share a port with HTTP servers, by having its handshake be a valid HTTP Upgrade request. One could conceptually use other protocols to establish client-server messaging, but the intent of WebSockets is to provide a relatively simple protocol that can coexist with HTTP and deployed HTTP infrastructure (such as proxies) and that is as close to TCP as is safe for use with such infrastructure given security considerations, with targeted additions to simplify usage and keep simple things simple (such as the addition of message semantics).
-
When an endpoint is to interpret a byte stream as UTF-8 but finds that the byte stream is not, in fact, a valid UTF-8 stream, that endpoint MUST _Fail the WebSocket Connection_. This rule applies both during the opening handshake and during subsequent data exchange.
-
The goal of this technology is to provide a mechanism for browser-based applications that need two-way communication with servers that does not rely on opening multiple HTTP connections (e.g., using XMLHttpRequest or <iframe>s and long polling).
Tags
- thin abstraction/layer
- design philosophy
- Websockets
- layers that build upon other layers to add more features (software)
- design goals
- well-written
- relationship between
- Internet protocols/standards
- motivation: why did you create this?
- illustrating problem
- TCP
- HTTP
- extensibility
- security
- better to fail loudly with an error than to fail subtly/silently
- WebSocket protocol
Annotators
URL
-