TE
科技回声
首页24小时热榜最新最佳问答展示工作
GitHubTwitter
首页

科技回声

基于 Next.js 构建的科技新闻平台,提供全球科技新闻和讨论内容。

GitHubTwitter

首页

首页最新最佳问答展示工作

资源链接

HackerNews API原版 HackerNewsNext.js

© 2025 科技回声. 版权所有。

Shitlist Driven Development (2016)

404 点作者 r4um超过 4 年前

36 条评论

reader_1000超过 4 年前
I don't remember the exact project or where I read it but one project added delay (using sleep function) to depreatected methods in order to discourage people using them. After every release, they increased the sleep time so that at one point it became impossible to use it without noticing it. Although I don't know if it is possible to do this for new code trying to use deprecated function and have old code use non-delayed one, I think it was a nice trick.
评论 #25435402 未加载
评论 #25438585 未加载
评论 #25434749 未加载
评论 #25434966 未加载
评论 #25432964 未加载
评论 #25435628 未加载
评论 #25438481 未加载
pbronez超过 4 年前
Here, a “shitlist” tracks existing uses of deprecated behavior within a large code base. It prevents new uses of deprecated behavior without disrupting legacy code. This is a temporary measure used to facilitate refactoring large code bases.
评论 #25431262 未加载
fduran超过 4 年前
This is a good example of &quot;Organization as Code&quot;, where you are trying to influence a non-trivial change (often &quot;cultural&quot;) by code.<p>Frequently it&#x27;s better to change behaviour this way than say, holding meetings and presentations.<p>A typical example is &quot;we want our developer to write more tests&quot; but there are few existing examples of test code to look at and when you write a test it takes forever to run, so you fix this by fixing the underlaying issues (which is bad or non-existing code), rather than making developers attend TDD presentations and just talking about a &quot;test culture&quot; for example.
评论 #25437393 未加载
dhosek超过 4 年前
If you don&#x27;t want people to use deprecated code, it&#x27;s essential to document what the replacement should be. In JavaWorld, this can be done through Javadoc. Just tagging a method or class with @Deprecated and leaving it there is the sort of thing that makes me want to hurt people.
评论 #25431742 未加载
评论 #25431133 未加载
评论 #25431096 未加载
评论 #25431301 未加载
DonHopkins超过 4 年前
It&#x27;s better to use a Shiterator, which can yield pieces of shit on demand, lazily enumerate them just in time, and generate infinite streams of shit, instead of allocating all your shit up front, and having your shit together in one place.
评论 #25431107 未加载
评论 #25431679 未加载
评论 #25434567 未加载
评论 #25431130 未加载
codeulike超过 4 年前
&#x27;Shitelist&#x27; would rhyme better with &#x27;Whitelist&#x27;
评论 #25430614 未加载
Jumziey超过 4 年前
Brilliant. It&#x27;s a really good compliment to strangling certain parts of a large code base.<p>As always the key is getting the information to the right people at the right time, and making it more difficult to make the wrong choices then the right choices.
评论 #25432107 未加载
评论 #25430183 未加载
WJW超过 4 年前
This is an excellent way of using your (hopefully) already existing testing and CI infrastructure to change a social problem into a technical problem. As we all know, technical problems are by far the easier of the two. :)<p>We used this technique to great effect at my previous day job, though under the more neutral name of &quot;ratchet&quot;.
评论 #25430055 未加载
Rafert超过 4 年前
The Ruby-based tooling has been released as open source: <a href="https:&#x2F;&#x2F;github.com&#x2F;Shopify&#x2F;deprecation_toolkit" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;Shopify&#x2F;deprecation_toolkit</a>
anonygler超过 4 年前
This is accomplished at Google using the build system. Your visibility declaration tells the build system what&#x27;s allowed to depend on a piece of code.<p>When deprecating old code, you can shut that door with a whitelist and gradually force consumers to migrate.<p>I really like how code is managed at Google.
dhd415超过 4 年前
A similar kind of automated mechanism is required in distributed systems that allow for rolling upgrades. New functionality in upgraded nodes can&#x27;t break not-yet-upgraded nodes and legacy behavior in not-yet-upgraded nodes has to be tolerated in upgraded nodes but only until the entire system is upgraded and then it is prohibited. Doing this wrong results in some really hard to fix production states.
gitgud超过 4 年前
On a somewhat related note: One of the biggest things I&#x27;ve noticed is that simpler pieces of software are less likely to be deprecated, whereas complex codebases quickly become legacy and abandoned...
评论 #25430883 未加载
donatj超过 4 年前
In a similar vein but on a smaller scale we have a number of tests for deprecated behaviors in our application code, and whitelist the existing code based on serializing the file name, method name, and the ordered list of parsed token <i>types</i> of the method.<p>That way minor alterations like changing a string or numeric value don&#x27;t remove the method from the whitelist, but alterations to the logic of the given method require you to fix the issue while you&#x27;re in there poking around already to pass CI.
molsson超过 4 年前
We used a similar approach when we pushed to get -Werror enabled in a large C++ code base I worked on years ago.
Remaged超过 4 年前
For the Java Developers here, have a look at archunit. We use this to discourage certain behaviour but you can also use it to test and whitelist the usage of shitlist items =&gt; <a href="https:&#x2F;&#x2F;www.archunit.org&#x2F;" rel="nofollow">https:&#x2F;&#x2F;www.archunit.org&#x2F;</a>
bravura超过 4 年前
A simpler hack is just to give deprecated methods unwieldly and obstreporous names like: `REMOVEME_old_function_name`
awinter-py超过 4 年前
I love his specific examples.<p>&gt; Make sure that a certain datastore is only read from in a certain context ... Ensure fallbacks for all uses of a secondary data-store ... joins between tables that have no business being joined<p>I wish linters &#x2F; typesystems were extensible enough to do this kind of domain-specific checking. There&#x27;s a new generation of static analysis that&#x27;s much more focused on architecture or business rules and is less about code-in-the-small concerns like class methods or operator compatibility.
javier10e6超过 4 年前
As software goes, years later there is going to be a shitlist_v_1 (bad classes) and a shitlist_v_2 (very bad classes) and on and on
ChrisMarshallNY超过 4 年前
That&#x27;s a pretty good idea.<p>I think a key to doing large, multi-developer projects, is true modular design, with opaque APIs, and each module with its own project identity and lifecycle.<p>Not a particularly popular stance, as it means a lot more overhead in each project.<p>It does reduce the need for shitlists, though.
mcv超过 4 年前
Even in a single-team project, I&#x27;ve ran into the problem that I&#x27;m refactoring some old code while others keep adding to it. Some way to have to cause failing tests sounds like a great idea.
jbackus超过 4 年前
Another cool way you could do this: Ruby methods can ask for their caller_locations. They work like this:<p><pre><code> # Source $ cat example_for_hn.rb def foo bar end def bar baz end def baz (c1, c2) = caller_locations.first(2) puts &quot;Parent caller: &#x27;#{c1.label}&#x27; in &#x27;#{c1.path}&#x27;&quot; puts &quot;Grandparent caller: &#x27;#{c2.label}&#x27; in &#x27;#{c2.path}&#x27;&quot; end foo # Demo $ ruby example_for_hn.rb Parent caller: &#x27;bar&#x27; in &#x27;example_for_hn.rb&#x27; Grandparent caller: &#x27;foo&#x27; in &#x27;example_for_hn.rb&#x27; </code></pre> So, you could define a method decorating class method like so:<p><pre><code> module Shitlist def shitlist(method_name, whitelist) original_method = instance_method(method_name) undef_method(method_name) define_method(method_name) do |*args, &amp;block| call = caller_locations.first passes_whitelist = whitelist.any? do |label, file_pattern| call.label == label &amp;&amp; call.absolute_path.end_with?(file_pattern) end unless passes_whitelist fail &quot;Shitlisted method! Permitted callers: #{whitelist}&quot; end original_method.bind(self).call(*args, &amp;block) end end end </code></pre> and then extend classes with it to use the decorator:<p><pre><code> class Example extend Shitlist def not_on_shitlist qux end def baz qux end def qux puts &#x27;Only some methods can call me :)&#x27; end shitlist :qux, &#x27;baz&#x27; =&gt; &#x27;shitlist.rb&#x27; end </code></pre> If I run this example (full source: <a href="https:&#x2F;&#x2F;git.io&#x2F;JLOdV" rel="nofollow">https:&#x2F;&#x2F;git.io&#x2F;JLOdV</a>), the non-whitelisted caller throws an error:<p><pre><code> $ ruby shitlist.rb Only some methods can call me :) Traceback (most recent call last): 2: from shitlist.rb:44:in `&lt;main&gt;&#x27; 1: from shitlist.rb:25:in `not_on_shitlist&#x27; shitlist.rb:13:in `block in shitlist&#x27;: Shitlisted method! Permitted callers: {&quot;baz&quot;=&gt;&quot;shitlist.rb&quot;} (RuntimeError) </code></pre> ---<p>Of course, you might not want this hijacked method with tracing inside something performance critical. You could always configure the implementation to be a no-op in production.
quickthrower2超过 4 年前
Got this T-shirt! It’s useful in regular sized code bases too. We used it for certain kinds of linting and code style errors.
gwbas1c超过 4 年前
I&#x27;m more curious about how things like shitlists are implemented in different languages.<p>Most of my experience is C#, where calling deprecated code triggers a warning.<p>Considering that C# warnings will fail in CI, how would someone do a C# shitlist? Would it require some kind of #pragma, that would stick out like a sore thumb in a code review
评论 #25440006 未加载
评论 #25436281 未加载
评论 #25431641 未加载
评论 #25431293 未加载
mellosouls超过 4 年前
To an extent this seems to be related to more general automated detection of refactor targets&#x2F;&quot;code smells&quot; (ironically) for which there exist tools already (e.g. linters indicated in the article) - I like this simple &quot;list&quot; approach though.
chapium超过 4 年前
Love the concept, hate the name. To me this seems like the recycle bin concept. Allow the code to exist temporarily, but encourage permanent deletion. Perhaps a better name could be a &quot;screamlist&quot; or &quot;needstochange&quot; list.
评论 #25431503 未加载
Tade0超过 4 年前
I kept a personal shitlist in one project but it was rather a collection of &quot;worst practices&quot; - things I vowed never to do.<p>It was personal because the idea didn&#x27;t get a lot of attention when I brought it up.
closeparen超过 4 年前
We use Bazel’s visibility settings this way. More often for controlled beta rollouts than for deprecation, but same principle. You can make it a compile time error to import a package that isn’t for you.
评论 #25433884 未加载
csutil-com超过 4 年前
I love that C# supports deprecation as a language feature and allows to mark an obsolete method as only usable by other deprecated methods, which is the same as the shitlist approach here in the end
Uberphallus超过 4 年前
Shitlist driven migration&#x2F;refactor, maybe. If it&#x27;s <i>development</i> it means you&#x27;re always deprecating something and that&#x27;s a significant organizational smell.
评论 #25431085 未加载
weeboid超过 4 年前
Very difficult to sell something named &quot;Shitlist&quot;
评论 #25434466 未加载
baxtr超过 4 年前
In case you wonder what shitlist means:<p><i>&gt; “shitlists”: a whitelist of deprecated behaviour. Existing deprecated behaviour is OK and whitelisted.</i>
mleonhard超过 4 年前
The article shows ways to prevent new dependencies on your deprecated library&#x2F;service. This is half of the problem. The other half is efficiently removing the existing dependencies.<p>Your team could change the other teams&#x27; code to remove the dependencies. This is usually inefficient. You will waste time learning their code. They may drag out the code review process for weeks or months.<p>Some teams may refuse to accept your changes and use your service deprecation as political capital to demand more headcount. They may even lie to their managers and claim that the dependency deprecation is justification for a rewrite that they want to do.<p>There is a technical solution that can help with this social problem: AUTOMATICALLY EXPIRING DEPENDENCY APPROVALS. Configure your library to allow only existing systems to use it, and make them all break on a certain date. Then, instead of forcing the other team to move, they have to move or their build breaks. And if they want to delay turndown they must convince you to change your code. Without automatic expiration, they can delay turndown by simply ignoring you.<p>Some teams may wait for the dependency expiration, lie saying they didn&#x27;t know about the turndown, and then demand that you delay the turndown and give them more time. You can work around this with a two-phased turndown. First create a new version of the library that allows only existing clients. Give the library a hideous name so code owners will want to remove it. Example: Deprecated_LiBrArY_YoUr_BuIlD_WiLL_BREaK_oN_20200601_LOL_Were_sERIUS_YOLO_exxtensuns_COme_frun_SVP_DaniELs_OnLY. Then set the existing library to expire in a week and email all users. They can easily switch to the new hideously-named library and in the process acknowledge that they know that their build will break at the specified date.<p>TLDR: Use expiring white lists so you won&#x27;t get ignored. Rename your deprecated library to something hideous to motivate code owners to migrate away from it.
kenerwin88超过 4 年前
Such a great idea, thank you for sharing!
TeeWEE超过 4 年前
Much better to annotate those functions with @deprecated and allow running in &quot;deprecated allow mode&quot; and a &quot;deprecated fail mode&quot;...<p>Never use profanity in your code, nor in your comments. Lets keep things professional.
评论 #25431489 未加载
评论 #25431552 未加载
评论 #25431524 未加载
评论 #25431529 未加载
einpoklum超过 4 年前
One can&#x27;t always introduce a multitude of shitlists into different places in the code. This can impact performance and readability; and perhaps even more importantly - if the language used is not high-level with reflection capabilities, you will be counting on callers&#x27; participation in calling the semi-deprecated API with truthful &quot;usage key&quot; for looking up on the shitlist. Who&#x27;s to say nobody reuses authroized keys for expediency?
jensneuse超过 4 年前
I will probably remember Sirupsen forever for his move of breaking Golang projects by renaming his github username. This led to go modules freaking out because different project used different name casing for the dependency. He has a popular logging library and go modules are angry when you rename github usernames..
评论 #25431210 未加载
评论 #25432085 未加载