2012-12-13 21 views
5

Tôi là newbie in rhino.Làm cách nào để bật 'cho ... trong' NativeJavaObject của tôi trong Rhino?

Hiện tại, tôi đang sử dụng khung công tác Rhino 1.7R thông qua .NET 4 và IKVM.NET. Tôi đã tiếp xúc với một số lớp được bọc thực thi NativeJavaObject sử dụng API setWrapFractory().

public class InterceptNativeObject : NativeJavaObject 
{ 
    public InterceptNativeObject() 
    { 

    } 

    public override Object get(String name, Scriptable start) 
    { 
     Object res = base.get(name, start); 
     if (res is NativeJavaMethod) 
     { 
      NativeJavaMethod method = (NativeJavaMethod)res; 
      return new RhinoMethodWrapFunction(method); 
     } 
     if (res == org.mozilla.javascript.UniqueTag.NOT_FOUND && 
      base.javaObject is IPropertBox && base.javaObject != null) 
     { 
      object ret = ((IPropertBox)base.javaObject)._x__GetPropertyValue(name); 

      return Utils.ConvertCLRValueToJavaValue(ret); 
     } 
     return res; 
    } 

    ..... 
} 

Bây giờ, tôi có thể truy cập tất cả các phương thức và thuộc tính .NET như tôi muốn.

Vấn đề hiện tại của tôi là hỗ trợ 'cho ... trong' các lớp NativeJavaObject của tôi. Khi tôi đánh giá

 'for(var prop in myClass){printf(prop);};' , 

nó trả về lỗi 'không' trong 'cuộc gọi không phải đối tượng'.

Có vẻ như) chức năng ('get' cố gắng tìm kiếm một đối tượng của '_ iterator _', nhưng nó dẫn đến 'không tìm thấy' tại get. Vì vậy, nó kết thúc với ngoại lệ. . Cho đến nay, tôi đã cố gắng

  • thêm java.util.Iterator
  • this.getIds return() GetEnumrator();

Không có tác phẩm nào.

Làm cách nào tôi có thể cho phép thuộc tính liệt kê quyền truy cập cho Wrapped NativeJavaObject của tôi? Giá trị lợi nhuận kỳ vọng của Rhino là '_ iterator _' để bật 'cho ... trong'?

Cảm ơn trước!

Trả lời

2

__iterator__ là một phần của Mozilla specific language extension. Liên kết đó giải thích rằng phương thức __iterator__ trả về một đối tượng có phương thức next ném StopIteration khi trình vòng lặp bị cạn.

Bạn phải opt in để lặp và phát mặc dù:

Để kích hoạt Javascript 1,7 hỗ trợ, bạn phải thiết lập các phiên bản như 170 sử dụng cuộc gọi Context.setLanguageVersion() API. Nếu bạn đang sử dụng vỏ tê giác, bạn có thể chỉ định -version 170 trên dòng lệnh hoặc phiên bản cuộc gọi (170) trong mã được thực thi bởi trình bao.

Bạn có thể viết JS trong tê giác rằng sẽ quấn một iterator Java để trình bày nó như một iterator JS:

function javaIteratorToJsIterator(javaIterator) { 
    return { 
    next: function() { 
     if (!javaIterator.hasNext()) { throw StopIteration; } 
     return javaIterator.next(); 
    } 
    }; 
} 

Ngoài ra, bạn có thể sử dụng máy phát điện phong cách Mozilla nhưng tôi nghĩ rằng bạn cần phải tạo trình thông dịch Rhino với tùy chọn bật chúng.

Trong khi trình vòng lặp tùy chỉnh là công cụ hữu ích, việc tạo của chúng yêu cầu lập trình cẩn thận do cần phải duy trì trạng thái nội bộ một cách rõ ràng.Máy phát điện cung cấp một giải pháp thay thế mạnh mẽ: chúng cho phép bạn xác định thuật toán lặp lại bằng cách viết một hàm duy nhất có thể duy trì trạng thái riêng của nó.

Máy phát điện là một loại chức năng đặc biệt hoạt động như một nhà máy cho các trình vòng lặp. Hàm sẽ trở thành một trình tạo nếu nó chứa một hoặc nhiều biểu thức năng suất.

+0

Cảm ơn bạn rất nhiều. "__iterator___" đang tìm kiếm một hàm để xử lý chứ không phải đối tượng. Tôi cũng sẽ thử với setLanguageVersion (170). Cảm ơn bạn một lần nữa vì đã cung cấp thông tin rất hữu ích! –

+0

Cuối cùng tôi đã lặp lại NativeJavaObject bằng cách tạo lớp Iterator là 'ScriptableObject'. Bây giờ nó chạy 'for (var a in document) {}' và 'if (' location 'trong cửa sổ) {}'. Cám ơn bạn một lần nữa! –

+0

@Yone, bạn được chào đón. Chúc mừng kịch bản. –