f <- function() 1
g <- function() 2
class(g) <- "function"
class(f) ## "function"
class(g) ## "function"
length.function <- function(x) "function"
length(f) ## 1
length(g) ## "function"
risposta
Innanzitutto, length
non è una tipica funzione generica, ma piuttosto un "Internal Generic Function". Si può vedere questo guardando la sua definizione:
> length
function (x) .Primitive("length")
Confronta questo per una tipica funzione generica:
> print
function (x, ...)
UseMethod("print")
<bytecode: 0x116ca6f90>
<environment: namespace:base>
length
chiamate direttamente in .Primitive
che poi può fare la spedizione, se non gestisce la chiamata in sé ; l'approccio tipico è chiamare direttamente UseMethod
che gestisce solo la spedizione. Si noti inoltre che non v'è alcuna funzione length.default
perché il codice nella chiamata .Primitive
lo fa:
> methods("length")
[1] length.function length.pdf_doc* length.POSIXlt
non sono sicuro che sia completamente definito quando un generico interno esaminerà metodi definiti dall'utente e quando sarà utilizzare solo interno quelli; Penso che l'idea generale sia che per una classe definita dall'utente (pacchetto, non core), verranno utilizzati i metodi forniti. Ma l'override per le classi interne può o non può funzionare.
Inoltre (sebbene non strettamente pertinente per questo caso), anche per un tipico metodo generico, la documentazione è ambigua riguardo a cosa dovrebbe accadere quando la classe viene derivata implicitamente piuttosto che come attributo. Innanzitutto, quali rapporti class()
rappresentano una fusione di cose. Dalla pagina class
aiuto:
Molti oggetti R hanno un attributo
class
, un vettore personaggio che dà i nomi delle classi da cui l'oggetto eredita. Se l'oggetto non ha un attributo di classe, ha una classe implicita,"matrix"
,"array"
o il risultato dimode(x)
(eccetto che i vettori integer hanno classe implicita"integer"
).
Così, nonostante class
restituire la stessa cosa per f
e g
, non sono la stessa cosa.
> attributes(f)
$srcref
function() 1
> attributes(g)
$srcref
function() 2
$class
[1] "function"
Ora, qui è dove diventa ambiguo. L'invio del metodo è descritto in (almeno) 2 punti: la pagina di aiuto class
e la pagina di aiuto UseMethod
. UseMethod
dice:
Quando viene applicata una funzione di chiamata
UseMethod("fun")
ad un oggetto con attributo classc("first", "second")
, il sistema cerca una funzione chiamatafun.first
e, se lo trova, lo applica all'oggetto. Se non viene trovata alcuna funzione di questo tipo, viene provata una funzione chiamatafun.second
. Se nessun nome di classe produce una funzione adatta, viene utilizzata la funzionefun.default
, se esiste, o si verifica un errore.
Mentre class
dice:
Quando una divertente funzione generica viene applicata a un oggetto con attributo class
c("first", "second")
, il sistema cerca una funzione chiamatafun.first
e, se lo trova, lo applica alla oggetto.Se non viene trovata alcuna funzione di questo tipo, viene provata una funzione chiamatafun.second
. Se nessun nome di classe produce una funzione adatta, viene utilizzata la funzionefun.default
(se esiste). Se non esiste un attributo di classe, viene provata la classe implicita, quindi il metodo predefinito.
La vera differenza è l'ultima frase che la pagina class
ha quel UseMethod
non lo fa. UseMethod
non dice cosa succede se non esiste un attributo class
; class
dice che la classe implicita è usata per la spedizione. Il tuo codice sembra indicare che ciò che è documentato in class
non è corretto, poiché length.function
sarebbe stato chiamato per g
.
Cosa succede nella distribuzione del metodo quando non c'è alcun attributo di classe probabilmente richiederà di esaminare il codice sorgente in quanto la documentazione non sembra essere di aiuto.
- 1. Differenza tra CTRL + G e Ctrl + F
- 2. lunghezza e lunghezza() in Java
- 3. Differenza tra val.length e val(). Lunghezza in jQuery?
- 4. Differenza di lunghezza delle stringhe tra rubino 1.8 e 1.9
- 5. Differenza tra le funzioni di Numel e lunghezza di MATLAB
- 6. Fortran: differenza tra estensione F e F
- 7. Differenza tra @Size, @Length e @Column (lunghezza = valore)
- 8. CryptoJS e lunghezza chiave/IV
- 9. PDO PARAM_STR e lunghezza
- 10. Perché PHP strlen() restituisce una lunghezza negativa?
- 11. lunghezza della stringa tra puntatori
- 12. Differenza tra if -e e if -f
- 13. Differenza tra append ("svg: g") e append ("g")
- 14. Lunghezza vs precisione
- 15. Perché ({} + {}). Lunghezza pari a 30?
- 16. differenza tra questo e l'auto in JavaScript
- 17. gruppi Balancing a lunghezza variabile lookbehind
- 18. Relazione tra input e lunghezza del testo cifrato in AES
- 19. Differenza tra -Wconversion tra il gcc e g ++
- 20. Differenza tra let, fun e function in F #
- 21. ServiceId.UniqueId lunghezza massima e formato
- 22. Networkx - Lunghezza percorso minima
- 23. F #: Differenza tra dizionario, Hashtable e Mappa
- 24. Differenza tra $ (this) e questo in jQuery
- 25. Perché la lunghezza del byte di una stringa è più lunga della lunghezza?
- 26. Perché specificare una lunghezza per i tipi di caratteri variabili
- 27. Couting di caratteri, parole, lunghezza delle parole e lunghezza totale in una frase
- 28. Array Lunghezza in Java
- 29. Perché ThreadSanitizer segnala una gara con questo esempio di blocco?
- 30. Perché "K" .Lunghezza mi dà risultati errati?
Benvenuti in SO! Per favore leggi [la pagina di aiuto] (http://stackoverflow.com/help/on-topic) per capire meglio come esprimere la tua domanda. Inoltre, si prega di utilizzare i tag del codice quando si condivide il codice. Puoi aggiungerli tramite l'editor. – Chrismas007
@Carlise: non fa per me (come dimostrato nella mia modifica). Penso che questo sia un interessante rompicapo sui meccanismi interni di R. –
Questo è interessante. Nota che 'attr (g," class ")' fornisce "function" ma 'attr (f," class ")' fornisce NULL. – Dason