2012-02-23 30 views
6

Có thể lấy số dòng hiện tại bằng __LINE__ trong Ruby hoặc Perl. Ví dụ:Tính năng __LINE__ trong Groovy

print "filename: #{__FILE__}, line: #{__LINE__}" 

Có tính năng tương tự trong Groovy không?

Trả lời

2

Không trực tiếp, nhưng bạn có thể lấy thông qua dấu vết ngăn xếp Ngoại lệ (hoặc Có thể bỏ qua). Ví dụ:

StackTraceElement getStackFrame(String debugMethodName) { 
    def ignorePackages = [ 
     'sun.', 
     'java.lang', 
     'org.codehaus', 
     'groovy.lang' 
    ] 
    StackTraceElement frame = null 
    Throwable t = new Throwable() 
    t.stackTrace.eachWithIndex { StackTraceElement stElement, int index -> 
     if (stElement.methodName.contains(debugMethodName)) { 
      int callerIndex = index + 1 
      while (t.stackTrace[callerIndex].isNativeMethod() || 
        ignorePackages.any { String packageName -> 
         t.stackTrace[callerIndex].className.startsWith(packageName) 
        }) { 
       callerIndex++ 
      } 
      frame = t.stackTrace[callerIndex] 
      return 
     } 
    } 
    frame 
} 

int getLineNumber() { 
    getStackFrame('getLineNumber')?.lineNumber ?: -1 
} 

String getFileName() { 
    getStackFrame('getFileName')?.fileName 
} 

String getMethodName() { 
    getStackFrame('getMethodName')?.methodName 
} 

def foo() { 
    println "looking at $fileName:$lineNumber ($methodName)" 
} 

foo() 

// ==> looking at test.groovy:39 (foo) 

Một lời cảnh báo mặc dù: nhận được số dòng, tên file, hoặc phương pháp như thế này là rất chậm.

+0

Tại sao nó quá chậm? Tương đương trong Perl (có nghĩa là, thông qua 'người gọi') là rất nhanh. – tchrist

+0

Dấu vết ngăn xếp Java có thể khá sâu sắc, hấp dẫn hơn nữa. Phương thức [Throwable.fillInStackTrace] (http://docs.oracle.com/javase/6/docs/api/java/lang/Throwable.html#fillInStackTrace%28%29) chỉ mất một lúc để tạo dữ liệu theo dõi chồng kết cấu. Xem http://stackoverflow.com/a/3980148/190201 để có cái nhìn sâu sắc hơn. Nó chắc chắn không phải là quá chậm để sử dụng để gỡ lỗi, nhưng nó là tốt để nhận thức được chi phí của nó trước khi sử dụng nó. – ataylor

1

Tôi không phải là chuyên gia trong Groovy, nhưng tôi không nghĩ vậy. Tôi biết rằng Java và C# không có nó.

Tính năng __LINE__ thực sự bắt đầu giúp gỡ lỗi trong C. C không có ngoại lệ hoặc nhiều tính năng khác hiện có ngôn ngữ, nhưng nó có macro mà trình biên dịch có thể mở rộng ở bất kỳ đâu trong mã, đó là lý do chúng tôi cần __FILE__, __LINE__, v.v. để cho chúng tôi biết chúng tôi đã ở đâu khi có điều gì đó xấu xảy ra. Đây là cách assert hoạt động trong C và C++. JVM có các công cụ gỡ lỗi rất tốt và kết hợp với assert và các ngoại lệ, bạn có thể dễ dàng xác định nơi đã xảy ra sự cố (ngăn xếp dấu vết tốt hơn chỉ là số dòng).

Tôi tin rằng lý do Ruby và Perl có các macro đó là do chúng được tạo bởi tin tặc C. Tôi chưa bao giờ sử dụng một trong hai ngôn ngữ đó đủ để biết mức độ hỗ trợ gỡ lỗi hoặc các macro thực sự hữu ích như thế nào.

+0

Tôi có thể xác nhận rằng chúng không thực sự được sử dụng nhiều. Cách thông thường để lấy thông tin về một khung trong Perl, cho dù bên trong trình gỡ lỗi hay bên ngoài của nó, là sử dụng hàm 'caller' với một số khung làm đối số. 0 là nơi bạn đang ở ngay bây giờ, 1 là người gọi của bạn, 2 là * người gọi * của anh ấy, v.v. Điều này hiện trả về gói, tên tệp, dòng, chương trình con của khung và một loạt các thứ khác của khung đó. Vì vậy, bạn thường sẽ sử dụng giao diện chức năng để lấy thông tin đó, không phải là các macro giả '__FILE__' và' __LINE__' giả. – tchrist

Các vấn đề liên quan