新たにオブジェクトを作る

  • 昨日の記事で、Rのオブジェクトの基本仕様を確認した
  • その中で、基本仕様外のオブジェクトとしてhashについて触れた
  • それは、hashによる値参照はプログラミングでは基本的な仕組みだから
  • さてhashパッケージを使って、hashというオブジェクトがどのように導入されたかを見てみよう
  • そうすることで、「新たにオブジェクトを作る」仕組みがわかる
  • ハッシュパッケージを読み込む
library(hash)
  • ハッシュパッケージのexamplesを回してみる
h <- hash( letters, 1:26 )
  h$a
  h$b
  h[[ "a" ]]
  h[ letters[1:3] ]

  h$a<-100
  # h[['a']]<-letters

  is.hash(h)
  • その実行結果
> h <- hash( letters, 1:26 )
>   h$a
[1] 1
>   h$b
[1] 2
>   h[[ "a" ]]
[1] 1
>   h[ letters[1:3] ]
<hash> containing 3 key-value pair(s).
  a : 1
  b : 2
  c : 3
> 
>   h$a<-100
>   # h[['a']]<-letters
> 
>   is.hash(h)
[1] TRUE
  • "is.hash(h)"でTRUEです
  • ではこれは「Rの基本仕様では」何なのか?をtypeof()関数で確かめてみる
typeof(h)
  • その実行結果は以下の通りで、"S4"であることがわかる。これは、Rで新たに定義されたもの、という意味
> typeof(h)
[1] "S4"
  • これでは、「そう、それで」的な情報なので、ハッシュ"h"を作った関数"hash()"の中身を覗いてみる
hash
  • その実行結果
> hash
function (...) 
{
    li <- list(...)
    h <- new("hash", new.env(hash = TRUE, parent = emptyenv()))
    if (length(li) > 0) {
        if (length(li) > 0) 
            .set(h, ...)
    }
    return(h)
}
<environment: namespace:hash>
  • "new()"という関数が使われていて、それによってオブジェクト"h"が作られていることがわかる
  • では"new()"関数が何かを調べてみる
help(new)
  • ヘルプ記事によれば"Generate an Object from a Class"する関数であることがわかる
  • じゃあ、Classクラスとはなんぞや、ということになる
  • "new()"関数のヘルプ記事に"Classes"のヘルプ記事へのリンクがあるから、それをたどる(R内から"help(Classes)"でも引ける)と、クラスは、新し区オブジェクトを定義していくときの仕組みであることがわかる
  • ヘルプ記事の冒頭の引用
Description

Class definitions are objects that contain the formal definition of a class of R objects, usually referred to as an S4 class, to distinguish them from the informal S3 classes. This document gives an overview of S4 classes; for details of the class representation objects, see help for the class classRepresentation.
  • さらなるクラスの詳細は、Classesのヘルプ記事から"classRepresentation"のヘルプ記事へ飛んで確認できる
  • ハッシュに戻って、では、hashという新規オブジェクトはどのように定義されているのか、ということを見てみよう
  • まずは、「普通の何か」のクラスに関する情報を見てみる
> getClass("numeric") ## a built in class
Class "numeric" [package "methods"]

No Slots, prototype of class "numeric"

Extends: "vector"

Known Subclasses: 
Class "integer", directly
Class "ordered", by class "factor", distance 3
> getClass("vector")
Virtual Class "vector" [package "methods"]

No Slots, prototype of class "NULL"

Known Subclasses: 
Class "logical", directly
Class "numeric", directly
Class "character", directly
Class "complex", directly
Class "integer", directly
Class "raw", directly
Class "expression", directly
Class "list", directly
Class "structure", directly, with explicit coerce
Class "array", by class "structure", distance 2, with explicit coerce
Class "matrix", by class "array", distance 3, with explicit coerce
Class "signature", by class "character", distance 2
Class "ObjectsWithPackage", by class "character", distance 2
Class "mts", by class "matrix", distance 4, with explicit coerce
Class "ordered", by class "factor", distance 3
Class "namedList", by class "list", distance 2
Class "listOfMethods", by class "namedList", distance 3
> getClass("list")
Class "list" [package "methods"]

No Slots, prototype of class "list"

Extends: "vector"

Known Subclasses: 
Class "namedList", from data part
Class "listOfMethods", by class "namedList", distance 2
> getClass("matrix")
Class "matrix" [package "methods"]

No Slots, prototype of class "matrix"

Extends: 
Class "array", directly
Class "structure", by class "array", distance 2
Class "vector", by class "array", distance 3, with explicit coerce

Known Subclasses: 
Class "array", directly, with explicit test and coerce
Class "mts", directly
> getClass("array")
Class "array" [package "methods"]

No Slots, prototype of class "array"

Extends: 
Class "matrix", directly, with explicit test and coerce
Class "structure", directly
Class "vector", by class "structure", distance 2, with explicit coerce
Class "vector", by class "matrix", distance 4, with explicit test and coerce

Known Subclasses: 
Class "matrix", directly
Class "mts", by class "matrix", distance 2
> getClass("factor")
Class "factor" [package "methods"]

Slots:
                                    
Name:      .Data    levels  .S3Class
Class:   integer character character

Extends: 
Class "integer", from data part
Class "oldClass", directly
Class "numeric", by class "integer", distance 2
Class "vector", by class "integer", distance 2

Known Subclasses: "ordered"
> getClass("data.frame")
Class "data.frame" [package "methods"]

Slots:
                                                                  
Name:                .Data               names           row.names
Class:                list           character data.frameRowLabels
                          
Name:             .S3Class
Class:           character

Extends: 
Class "list", from data part
Class "oldClass", directly
Class "vector", by class "list", distance 2
> try(getClassDef("hash"))
Class "hash" [package "hash"]

Slots:
                  
Name:       .xData
Class: environment

Extends: 
Class ".environment", directly
Class "environment", by class ".environment", distance 2, with explicit coerce
> try(getClass("hash"))
Class "hash" [package "hash"]

Slots:
                  
Name:       .xData
Class: environment

Extends: 
Class ".environment", directly
Class "environment", by class ".environment", distance 2, with explicit coerce
  • クラスを定義することについてはRjpWikiのこちらの記事も