문제

D String Mixins에 익숙하지 않은 사용자는 기본적으로 컴파일 타임 evals입니다. 템플리트 또는 Template MetapRogramming 또는 Compile Time 함수 평가에 의해 생성 된 리터럴 또는 생성 된 여부에 관계없이 컴파일 시간 문자열을 가져갈 수 있습니다. 간단한 문자열 리터럴을 사용하는 경우 기본적으로 컴파일러 자동 복사 - 붙여 넣기입니다.

인식하는 간단한 코드 재사용의 수단으로 리터럴의 문자열 믹스를 사용하는 것이 antipationn을 고려해야합니까? 한편으로는 기본적으로 컴파일러가 자동화 된 리터럴 복사본 및 붙여 넣기를 통해 한 번 혼합 된 경우 서로 다른 사람과 아무런 관련이 없습니다. String Mixin의 기호가 스코프가 혼합 된 기호로 충돌하면 나쁜 일이 발생합니다 (런타임이 아닌 컴파일 시간). 예를 들어, 특정 규칙에 따라 범위의 변수가 명명 된 경우에만 작동하는 경우에만 작동 할 기능의 중간에 문자열을 믹스 할 수있는 경우가 비교적 구조화되지 않습니다. Mixins는 외부 범위를 볼 수있는 변수를 선언 할 수 있습니다.

복사 및 붙여 넣기가 자동화 된 컴파일러이므로 소스 레벨에서 해당 코드에 대한 코드가 단일 진리가 있으며 수정 해야하는 경우에만 수정되어야합니다. 한 곳에서 모든 것이 동기화되어 있습니다. String Mixins는 또한 다른 방식으로 인식하기가 매우 어려운 코드를 크게 단순화하고 수동으로 삭감되고 붙여 넣을 확률이 매우 높습니다.

올바른 솔루션이 없습니다

다른 팁

당신이 제기 한 모든 비판은 사실입니다.

에 관계없이 수동 copypaste보다 여전히 우수합니다.

실제로, 내 도구 라이브러리, 문자열 테이블 확장에서 유사한 실행 중입니다.예제 코드, 경로 추적자의 동적 값 구현에서 :

  T to(T)() {
    static if (!is(T == Scope)) {
      T value;
      if (flatType == FlatType.ScopeValue) value = sr.value().to!(T);
    }
    const string Table = `
                 | bool          | int         | string               | float   | Scope
      -----------+---------------+-------------+----------------------+---------+----------
      Boolean    | b             | b           | b?q{true}p:q{false}p | ø       | ø
      Integer    | i != 0        | i           | Format(i)            | i       | ø
      String     | s == q{true}p | atoi(s)     | s                    | atof(s) | ø
      Float      | ø             | cast(int) f | Format(f)            | f       | ø
      ScopeRef   | !!sr          | ø           | (sr?sr.fqn:q{(null:r)}p) | ø   | sr
      ScopeValue | value         | value       | value                | value   | sr`;
    mixin(ctTableUnrollColMajor(Table,
      `static if (is(T == $COL))
        switch (flatType) {
          $BODY
          default: throw new Exception(Format("Invalid type: ", flatType));
        }
      else `,
      `case FlatType.$ROW:
        static if (q{$CELL}p == "ø")
          throw new Exception(q{Cannot convert $ROW to $COL: }p~to!(string)~q{! }p);
        else return $CELL;
      `
    ).litstring_expand() ~ `static assert(false, "Unsupported type: "~T.stringof); `);
  }
.

나는 끔찍한 중첩 된 ifs와 문자열 믹스가없는 사례 진술을 쉽고, 이런 식으로 모든 추함이 아래쪽에 집중되고 실제 행동 함수의 한 눈에서 읽기 쉽습니다.

While other, more elegant solutions may be better to use if you can, string mixins can be extremely useful. They allow for both code re-use and code generation. They're checked at compile time. The code that results is exactly the same as if you'de written it yourself by hand, so it's not any less safe than if you had written it yourself by hand.

The problem with string mixins is that they're harder to control than hand-written code in the sense that it's not physically laid out in your source in the same manner with line numbers clearly traceable to errors, and it may be harder to debug. For instance, take hello world with a string mixin:

import std.stdio;

void main()
{
    mixin(hello());
}

string hello()
{
    return "
    writeln(\"hello world\");
";
}

If we were to remove the semicolon after writeln(), then the error we got would be

d.d(7): found 'EOF' when expecting ';' following statement

The mixin is done on line 5. Line 7 is a blank line. So, the line number is of limited usefulness here. Now, this mixin is short enough that we could have put it on a single line and gotten it to say that the error was on the same line as the mixin, but with more complicated mixins, that obviously won't work. So, by using a string mixin, your ability to figure out where an error is is impaired. If the code is generated using CTFE, then it would become that much more difficult to figure out exactly what the code even looks like in order to figure out what's wrong with it. It's a lot like figuring out what code a C-style macro turns into, except that it could be worse because they could be generated rather than a direct replacement. However, they don't replace except where you explicitly tell them to, so they're much safer than C-style macros.

String mixins are totally safe, and there's nothing particularly wrong with them, but they do make maintenance harder in some ways. The corresponding hand-written code would be easier to debug. However, string mixins are powerful enough that they can do a lot of code generation for you and save you a lot of maintainence costs in that sense, and they allow you to re-use code, which can be a big maintanence gain as well.

So, whether using a string mixin is a good idea in a particular situation depends on that situation. I don't see anything particularly wrong with them, and I certainly wouldn't call them an anti-pattern, but there are both pros and cons to using them such that whether they're a good idea depends on what you're doing. In many cases, there are more elegant, cleaner solutions which would be better. In others, they're exactly what the doctor ordered.

Personally, I think that they're fantastic if you're looking to generate code, saving yourself the effort of having to write that code by hand, and possibly making it easier to generate correct code for a variety of situations and avoiding risking creating new bugs like you might have had you written it yourself in each of those places where you used the mixin. It also is one of the ways to just outright re-use code without having to worry about the cost of a function call or issues with the limits of single-inheritance or anything else that makes code re-use by calling functions or inheritance harder. You're simply copying and pasting the code into each place in a manner which makes it so that if you change the code, the changes will be properly pasted everywhere without you having to worry about tracking them all down like if you had hand copy and pasted.

So, use string mixins where appropriate, and it's probably best not to use them if they're not needed, but there's nothing really wrong with using them.

String mixin is like goto: it should be avoided where ever possible and should be used wherever required.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top