2015-01-09 18 views
8

Nếu bạn định nghĩa một biến bên trong một hàm tổng quát, nó có sẵn cho phương pháp này. Ví dụ:Phạm vi trong các chức năng chung R

g <- function(x) { 
    y <- 2 
    UseMethod("g") 
} 
g.default <- function() y 
g() 
[1] 2 

Nhưng nếu biến bạn xác định có cùng tên với tham số chức năng thì điều này không xảy ra. Dường như R xóa biến đó trước khi gọi phương thức:

g <- function(x) { 
    x <- 2 
    UseMethod("g") 
} 
g.default <- function() x 
g() 
Error in g.default() : object 'x' not found 

Ai đó có thể giải thích chính xác những gì đang xảy ra ở đây?

Trả lời

4

Các ý kiến ​​sau đây từ C source file that defines do_usemethod ít nhất gợi ý vào những gì đang xảy ra. Xem đặc biệt câu thứ hai của mục được liệt kê thứ hai. Về cơ bản, có vẻ như (do ứng dụng quy tắc câm ở điểm thứ hai), giá trị của x không được sao chép vì mã C kiểm tra xem nó có nằm trong số các formals hay không, do đó loại trừ nếu từ danh sách các biến được chèn vào môi trường đánh giá của phương thức.

/* usemethod - calling functions need to evaluate the object 
* (== 2nd argument). They also need to ensure that the 
* argument list is set up in the correct manner. 
* 
* 1. find the context for the calling function (i.e. the generic) 
* this gives us the unevaluated arguments for the original call 
* 
* 2. create an environment for evaluating the method and insert 
* a handful of variables (.Generic, .Class and .Method) into 
* that environment. Also copy any variables in the env of the 
* generic that are not formal (or actual) arguments. 
* 
* 3. fix up the argument list; it should be the arguments to the 
* generic matched to the formals of the method to be invoked */ 
+0

Tôi đồng ý rằng đây là lý do tại sao điều này xảy ra. Tuy nhiên, để "làm việc xung quanh" này, nếu bạn muốn thay đổi các đối tượng mà bạn đang gửi đến chung chung, bạn nên vượt qua nó như tham số thứ hai cho 'UseMethod()'. Ngoài ra, nó sẽ được tốt đẹp nếu bạn thực hiện chung chung tất cả ít nhất là chia sẻ một đối số đầu tiên phổ biến. Thật kỳ lạ khi 'g.default()' không có tham số. Đây là nơi mà người ta mong đợi sẽ vượt qua 'x' đã sửa đổi. – MrFlick

+0

@MrFlick - Nhưng như bạn có thể nhìn thấy, thậm chí là đối số thứ hai cho 'UseMethod' không có được thông qua cùng. Nó chỉ được sử dụng để xác định phương pháp nên được gửi đi (mà trong trường hợp bất kỳ có vẻ như điều bạn nên muốn từ cuộc gọi chức năng chung của bạn). Tôi đồng ý với khuyến nghị chung của bạn về cách cấu trúc danh sách đối số của một số phương pháp. –

+0

@MrFlick - Tôi phải thừa nhận, mặc dù, rằng cho đến bây giờ tôi đã không đánh giá cao mà bạn có thể * *, nếu bạn muốn, sử dụng 'UseMethod()' cử dựa trên các giá trị của một vài đối số cung cấp khác nhau (hơn giống như những gì xảy ra với lớp S4). Nó sẽ đòi hỏi một chút hoặc tiền xử lý trong cơ thể của chung chung, nhưng có vẻ như nó sẽ không quá khó để thực hiện. Tôi tự hỏi nếu nó được sử dụng trong bất kỳ gói R nổi tiếng. –

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