それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

Pulse Secure の常駐プロセスの自動起動が鬱陶しい

pulse secure が自動起動してmacOS Xの起動を妨害する。

なんなんだマジでこのソフト・・・

自動起動をオフにして、必要なときだけ有効にすることにする。

takuya@~/Library$ launchctl load -w /Library/LaunchAgents/net.juniper.pulsetray.plist
takuya@~/Library$ launchctl unload -w /Library/LaunchAgents/net.juniper.pulsetray.plist

netatalk サーバーのアイコンを変える

netatalk の設定 afp.conf を見てたら

mimic

ミミック(擬態)という設定項目を発見!

早速設定してみた

ミミックすると、afp でMacから見えるアイコンが変わる。

  • afp.conf 書換
  • systemctl restart netatlk.conf
  • macOS X 側で Finder 再起動

mimic = Macmini

Mac Mini になった! f:id:takuya_1st:20160618173235p:plain:w300

mimic = MacPro

ゴミ箱になることを期待したけど、ゴミ箱にならなかった。残念

f:id:takuya_1st:20160618173323p:plain:w300

mimic = windows

OSX時代からのWindowsへの扱いが「怨念」こもってるwwやばい。

f:id:takuya_1st:20160618173417p:plain:w300

他にも色々

MacBookPro MacbookAir や AppleTV, Airpot(タイムカプセル)などが有りました。。

PowerBook, PowerMac, Macmini, iMac, MacBook, MacBookPro, MacBookAir, MacPro, AppleTV1,1, AirPort.

Windowsがあったので、他にもあるかも?

参考資料

afp.conf

juniper/Junos Pulse secure クライアントの代替にopenconnectを使う。

pulse secure を使うとSSL-VPNが張れるのですが。

Pulse SecureはOSの起動時に起動して起動を妨害する。とても邪魔

代替ソフトを探した

openvpn は方式が完全に違うから無理。jnc は jar のインストールが面倒くさいから見送り

openconnect が便利だった、

brew install openconnect
brew cask install tuntap

tuntap は openvpn などでも使われるので入ってることが多い

接続する

sudo openconnect --user takuya secure.example.jp --juniper

オプションに --juniper をつければ pulse secure の互換になる。

注意

DNS の設定が変わるので、macOS X だとWiFiDNS設定がぐちゃぐちゃになった。

この辺は今後使いながら調べる必要がありそう。

参考資料

http://www.infradead.org/openconnect/manual.html

linux にmac の タイムマシンサーバーを作る。

タイムマシンサーバーを作る。

タイムカプセル、高い。高いよ。バックアップを取るのにちょっと不便だよ。

netatalk で タイムカプセルを作る

Samba にsparse bundle を作る手もあるけれど、Sambaだとバックアップが途切れた時に不便なので。AFPで構成しています。

Debian Jessie にアプグレしたので作りなおした。

Debian LTSが Wheezy から Jessie になったので、合わせて作りなおしました。

変更点としては sysv-init から systemd に変わったところに合わせる感じです。

準備

必要な素材(ビルド用)を持ってきます。

sudo apt install build-essential \
 libevent-dev \
 libssl-dev \
 libgcrypt11-dev \
 libpam0g-dev \
 libwrap0-dev \
 libdb-dev \
 libtdb-dev \
 avahi-daemon \
 libavahi-client-dev \
 libacl1-dev \
 libldap2-dev \
 libcrack2-dev \
 systemtap-sdt-dev \
 libdbus-1-dev \
 libdbus-glib-1-dev \
 libglib2.0-dev \
 tracker \
 libtracker-sparql-1.0-dev \
 libtracker-miner-1.0-dev \
 libkrb5-dev \
 libmysqlclient-dev \

ソースを取得して展開します。

curl  -L https://sourceforge.net/projects/netatalk/files/netatalk/3.1.8/netatalk-3.1.8.tar.gz | tar zxvf -
cd netatalk-3.1.8

コンパイルします。

./configure \
        --with-init-style=debian-systemd \
        --without-libevent \
        --without-tdb \
        --with-cracklib \
        --enable-krbV-uam \
        --with-pam-confdir=/etc/pam.d \
        --with-dbus-sysconf-dir=/etc/dbus-1/system.d \
        --with-tracker-pkgconfig-version=1.0

systemd を選択するところがポイント、PAMでユーザー認証するので PAM のパスを書いてある。

make clean && make -j 3 

無事にビルドが終わったことを確認します。

 ./etc/afpd/afpd -V
afpd 3.1.8 - Apple Filing Protocol (AFP) daemon of Netatalk

This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version. Please see the file COPYING for further information and details.

afpd has been compiled with support for these features:

          AFP versions: 2.2 3.0 3.1 3.2 3.3 3.4
         CNID backends: dbd last tdb mysql
      Zeroconf support: Avahi
  TCP wrappers support: Yes
         Quota support: Yes
   Admin group support: Yes
    Valid shell checks: Yes
      cracklib support: Yes
            EA support: ad | sys
           ACL support: Yes
          LDAP support: Yes
         D-Bus support: Yes
     Spotlight support: Yes
         DTrace probes: Yes

              afp.conf: /usr/local/etc/afp.conf
           extmap.conf: /usr/local/etc/extmap.conf
       state directory: /usr/local/var/netatalk/
    afp_signature.conf: /usr/local/var/netatalk/afp_signature.conf
      afp_voluuid.conf: /usr/local/var/netatalk/afp_voluuid.conf
       UAM search path: /usr/local/lib/netatalk//
  Server messages path: /usr/local/var/netatalk/msg/

インストール

あとあと管理が楽なので、checkinstall を使います。

sudo apt install checkinstall
sudo checkinstall   \
   --pkgname=netatalk3.1.8 \
   --pkgversion="1:$(date +%Y%m%d%H%M)"  \
   --backup=no \
   --deldoc=yes \
   --fstrans=no \
   --default

インストールしたファイルを確認するときは sudo dpkg -L netatalk3.1.8

初期設定しておきます。

インストールのターゲットが /usr/local/だったので、設定は /usr/local/etcにあります。

これだと、忘れそうで不便なので、ln しておきます。

sudo ln -s  /usr/local/etc/afp.conf /etc/

設定ファイルを書きます。

;
; Netatalk 3.x configuration file
;

[Global]
    uam list = uams_dhx2_passwd.so
    mac charset = MAC_JAPANESE
    hostname = acid-afp
    vol preset = default_for_all_volumes
    log file = /var/log/netatalk.log
    #log level = default:maxdebug
    log level = default

    dbus daemon = /usr/bin/dbus-daemon

[default_for_all_volumes]
    file perm = 0600
    directory perm = 0700

[Homes]
    basedir regex = /home

[videos]
    path = /var/video/
    time machine = no


[My Time Machine Volume]
    path = /home/takuya/time_capsule/
    time machine = yes
    vol size limit = 450000

今回はuam list = uams_dhx2_passwd.so が必要だった。コレを入れないとPAM通して認証済みログ出てるのに、なぜかドライブが見えなかった。

起動する

sudo service netatalk restart

systemd に認識されてることを確認

sudo systemctl status netatalk
sudo systemctl start netatalk
sudo systemctl status netatalk

systemd に自動起動するように確認

service に登録されてるか確認

sudo systemctl  list-units --type=service | grep netatalk

再起動する。

sudo systemctl enable netatalk
sudo reboot
sudo systemctl status netatalk

関係ないけど、systemd になってこの作業がめんどくさくてやだ。。。忘れて、起動しない&設定反映しないで、焦ること多数。

見えたよ

f:id:takuya_1st:20160617003937j:plain:w600

タイムカプセルとして使えるようになった。

f:id:takuya_1st:20160617003938j:plain:w600

ログインする方法

デフォルトのままで。わたしは、linux のユーザ名でログインする方法にしました。

詳しくは→ http://netatalk.sourceforge.net/3.1/htmldocs/configuration.html#authentication

基本的には /etc/passwd (PAM) にユーザ認証を任せる感じ

/etc/pam.d/netatalk
#%PAM-1.0
auth     include common-auth
account  include common-account
password include common-password
session  include common-session

Sambaもあるとき

同一サーバーにSamba も afp あるときは、同名のホスト名で、共有される。Macのネットワーク一覧でAFPが優先されて見えちゃうので、Sambaがネットワークから見えなくなる。名前が被っちゃう。

なので、ホスト名を変えておくことで、同時に使うことが出来る。

# なにもしないと `hostoname`=myserver
    hostname = myserver-afp 

Sambaがあるときは設定を変えることで使いやすくなる。

Sambaより楽かも

Samba4系で AD サーバーになったので設定があれこれめんどくさくなった。macOS X からのデータ共有ならAFPとnetatlk のほうが手軽でいいや

netatalk なら spotlight にも対応するし。必要ならtdb使えるし、持っておいて損はない。

将来的にはSMBでもタイムマシーンが使えるらしいが。。。

macOS SierraおよびServer 5.2ではSMB接続のネットワークボリュームを「Time Machine」のバックアップディスクとして使用可能に? | AAPL Ch.

いつNetatalkを捨てて、Sambaに移行すべきか:HAT blog

AFP は将来的には使えなくなる・・・だと?ええ、、SMBで共有するとなるとそれはそれめんどくさいよね。そもそもLinuxのSMBでtime capusle に使えるのかな・・・

過去資料

http://takuya-1st.hatenablog.jp/entry/2014/04/07/013519

2017-03-01

systemd 関連を一部修正

参考資料

http://netatalk.sourceforge.net/3.0/htmldocs/afp.conf.5.html

http://netatalk.sourceforge.net/wiki/index.php/Install_Netatalk_3.1.8_on_Debian_8_Jessie

http://d.hatena.ne.jp/m-bird/20120925/1348595321

expect自動入力 を python で実現する

expect 便利ですよね。

expect コマンドがあればターミナルの自動入力が出来ます。

ruby でも使ってました。 でも ruby は gems がもう地獄でちょっとずつ python / javascript に移行しようと思っています。

使い方:import

import pexpect

起動と処理待ちは spawn

import pexpect

prc = pexpect.spawn("find")
prc.expect( pexpect.EOF )

コマンドの終了待ちは EOFで行います。

出力結果がほしい時

sys.stdout につなげます。

import pexpect
import sys

prc = pexpect.spawn("find")
prc.logfile = sys.stdout
prc.expect( pexpect.EOF )

文字列の送信

基本的な使い方が分かったので入力する。

import pexpect
import sys

prc = pexpect.spawn("ssh user@192.168.2.1 ")
prc.logfile = sys.stdout
prc.expect("password:")
prc.sendline("PASSWORD")
prc.expect( pexpect.EOF )

これでパスワードは入力できる。基本的なところが分かった。

spawn は 通常の spawn と同じ

prc = pexpect.spawn("ssh",["user@192.168.2.1 "] )

オプションを使うときは配列で与えてもいいし、パイプも使えるし。

すごく楽ですね。

なぜか、うちの環境にはpexpect が最初から入ってた。。。python 素晴らしい。

参考資料

Core pexpect components — Pexpect 4.1.0 documentation

File.rename でハマった。

File.rename はデバイスを超えてrename 出来ない。

File.rename を何気なく使っていました。 require 'fileutils' するのが面倒くさいという、それだけの理由で。

そして今日は見事にドハマリした。cron でエラーが出ているので追いかけてみたら。なんとrename出来ないというerror

File.rename # too bad

FileUtils.mv # good manner

まさか、ブロックデバイスが異なると rename 出来ないなんて予想もしなかった。システムコールがそうなってるんだろうけど。油断した。

パーティションを超えてコピーやリネーム、移動、ファイルの変更が発生するおそれがあるので、 File.rename はよほどのことがないと使ってはいけない。

require が面倒くさいとか言う理由で避けてた自分が馬鹿でした

lsblk が便利だった。物理ディスクの一覧を見る。

lsblk で物理ディスクの一覧を見ることが出来る。

PCにどのようなHDDが何台つながっているか見ることが出来る。さらにマウントポイントも確認できて便利でした。

takuya@:~$ lsblk
NAME          MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sda             8:0    0   1.8T  0 disk /mnt/464fb75d
sdb             8:16   0 223.6G  0 disk
├─sdb1          8:17   0   9.3G  0 part
├─sdb2          8:18   0     1K  0 part
├─sdb5          8:21   0   954M  0 part [SWAP]
└─sdb6          8:22   0 186.3G  0 part /
sdc             8:32   0 931.5G  0 disk
├─sdc1          8:33   0   243M  0 part
├─sdc2          8:34   0     1K  0 part
└─sdc5          8:37   0 931.3G  0 part
  └─atom-root 254:0    0   120G  0 lvm
sdd             8:48   0   1.8T  0 disk
└─sdd1          8:49   0   1.8T  0 part /home/takuya/123
sde             8:64   0   2.7T  0 disk /mnt/12345
sr0            11:0    1     1T  0 rom
loop0           7:0    0   120G  1 loop /mnt/123

このコマンドはHDDが増えてきた自宅マシンでどこにどうマッピングされているのかを確認するときに便利ですね。

lsblk の豊富なオプション

lsblk には豊富なオプションが用意されていて、書くにするときに大変重宝する。

lsblk -O 

すべての表示可能な情報をテーブルで表示できる

ファイルシステムだけ表示する

lsblk -fs 

知らなかった。

すごく便利ですねコレ。

使い方:
 lsblk [オプション] [<デバイス> ...]

オプション:
 -a, --all            すべてのデバイスを表示します
 -b, --bytes          可読性の高い形式ではなく、バイト単位でサイズを表示します
 -d, --nodeps         スレーブデバイスやホルダーを表示しません
 -D, --discard        discard 関連の機能を表示します
 -e, --exclude <一覧> メジャー番号を利用して、除外するデバイスを指定します (既定値: RAM ディスク)
 -f, --fs             ファイルシステムに関する情報を出力します
 -i, --ascii          ASCII 文字のみを使用します
 -I, --include <一覧> 指定したメジャー番号のデバイスのみを表示します
 -l, --list           一覧形式で出力します
 -m, --perms          パーミッションに関する情報を出力します
 -n, --noheadings     ヘッダを表示しないようにします
 -o, --output <list>  出力する列を指定します
 -O, --output-all     output all columns
 -p, --paths          完全なデバイスパスを表示します
 -P, --pairs          キー="値" の出力形式を使用します
 -r, --raw            加工を行なわない出力形式を使用します
 -s, --inverse        依存関係を逆転します
 -S, --scsi           SCSI デバイスに関する情報を出力します
 -t, --topology       トポロジに関する情報を出力します
 -x, --sort <column>  sort output by <column>

 -h, --help     このヘルプを表示して終了します
 -V, --version  バージョン情報を表示して終了します

利用可能な列 (--output で指定します):
        NAME  デバイス名
       KNAME  カーネル内部デバイス名
     MAJ:MIN  メジャー:マイナーデバイス番号
      FSTYPE  ファイルシステムの種類
  MOUNTPOINT  マウントされている場所
       LABEL  ファイルシステムのラベル
        UUID  ファイルシステムの UUID
    PARTTYPE  partition type UUID
   PARTLABEL  パーティションのラベル
    PARTUUID  パーティション UUID
   PARTFLAGS  パーティションフラグ
          RA  デバイスの先読み
          RO  読み込み専用デバイス
          RM  リムーバブルデバイス
       MODEL  デバイス識別子
      SERIAL  ディスクのシリアル番号
        SIZE  デバイスのサイズ
       STATE  デバイスの状態
       OWNER  ユーザ名
       GROUP  グループ名
        MODE  デバイスノードのパーミッション
   ALIGNMENT  アライメントオフセット
      MIN-IO  最小 I/O サイズ
      OPT-IO  最適 I/O サイズ
     PHY-SEC  物理セクタサイズ
     LOG-SEC  論理セクタサイズ
        ROTA  ローテーションデバイス
       SCHED  I/O スケジューラ名
     RQ-SIZE  要求キューサイズ
        TYPE  デバイスの種類
    DISC-ALN  discard アライメントオフセット
   DISC-GRAN  discard 粒度
    DISC-MAX  discard 最大バイト
   DISC-ZERO  discard ゼロデータ
       WSAME  write-same 最大バイト
         WWN  ユニークなストレージ識別子
        RAND  乱数シードへの追加
      PKNAME  親のカーネル内部デバイス名
        HCTL  SCSI 向けのホスト:チャンネル:ターゲット:LUN
        TRAN  デバイス伝送タイプ
         REV  デバイスのリビジョン
      VENDOR  デバイスの製造元

diskutil コマンドの bash_completion をぱぱっと書いた

かなりザックリですが

書いたのでメモ。

diskutil コマンドは使うときは頻繁に使うのに、使わない時は全く使わない変わったコマンド。

サブコマンドをよく忘れるのでcompetion にしておいた

gist.github.com

macOS で ext4 をread/write でマウントする。

2018-03-03 追記 ext4fuse が便利 → この文章の最後を参照してください

以下のバージョンで、R/W 出来ることを確認した。

Version: ext4fuse-0.1.3
OSXFUSE 2.8.5 

エントリ末尾の 追 記 に書きました。

最新版を使う限りでは、以下のext2での強制FUSEマウントは不要になったようです。

ext4 は write 出来ない。

ext4 はwrite マウントできない。

sudo ext4fuse /dev/disk3s2 mnt  -o allow_other # read only

El Capitan 以降のSIPには注意が必要*1

ext4fuse を使うと、読み込みのみ、書き込みできない。

ではどうするか。ext2 でマウントする。

まさかの互換性を利用した回答。そうかその手があったか。

 sudo fuse-ext2 -o force  /dev/disk3s2 mnt

ああああああああ、盲点だったぁ

mount 出来たぁっ

takuya@~/Desktop/mnt$ mount
/dev/disk1 on / (hfs, NFS exported, local, journaled)
/dev/disk3s2 on /Users/takuya/.Desktops/2016-04-24/mnt (osxfusefs_ext2, local, synchronous)
takuya@~/Desktop/mnt$ ll
total 88
drwxr-xr-x   2 root wheel  4096 2016-05-31 01:34 bin
drwxr-xr-x   2 root wheel  4096 2016-02-26 10:04 boot
drwxr-xr-x   4 root wheel  4096 2016-02-26 10:00 dev
drwxr-xr-x 114 root wheel  4096 2016-06-06 23:52 etc
drwxr-xr-x   5 root wheel  4096 2016-03-12 01:43 home
drwxr-xr-x  19 root wheel  4096 2016-05-31 01:43 lib
drwx------   2 root wheel 16384 2016-02-26 11:07 lost+found
drwxr-xr-x   2 root wheel  4096 2016-02-26 09:57 media
drwxr-xr-x   3 root wheel  4096 2016-04-10 05:31 mnt
drwxr-xr-x   7 root wheel  4096 2016-05-31 01:41 opt
drwxr-xr-x   2 root wheel  4096 2015-01-07 11:09 proc
drwx------   5 root wheel  4096 2016-06-06 23:52 root
drwxr-xr-x   5 root wheel  4096 2016-02-26 10:06 run
drwxr-xr-x   2 root wheel  4096 2016-05-31 01:35 sbin
drwxr-xr-x   2 root wheel  4096 2016-02-26 09:57 srv
drwxr-xr-x   2 root wheel  4096 2015-04-12 19:19 sys
drwxrwxrwt   7 root wheel  4096 2016-06-07 00:13 tmp
drwxr-xr-x  11 root wheel  4096 2016-05-31 01:41 usr
drwxr-xr-x  11 root wheel  4096 2016-02-26 11:21 var

参考資料

http://tex-numerics.blogspot.jp/2013/05/read-and-write-ext4-file-system-on-mac.html

2016-09-04 追加 ext4fuse のみでいける

El CapitanSIP system integrity protection 関連かな?ただマウントしただけではPermissionがおかしくて読み込めなかった。

sudo ext4fuse -o allow_other /dev/disk4s2 /mnt

Finder に出てくる mnt ポイントは指定するがOSX通常の/Volに出て来るので注意。 f:id:takuya_1st:20170310210226p:plain

2018-03-03

ちゃんと今でもできることを確認

関連資料

OSX 10.10.1 Yosemite で Fuse でext4使おうとしたら fuse インストール出来ない - それマグで!

*1:2016-09-04 確認 -o allow_other をつけないとマウントできなくなった

linux にフォントを追加する

debian / ubuntu の場合のフォントの追加方法

追加したいフォントを

~/.fonts

以下の好きな場所に置けば大丈夫。

システム全体で使うシステムフォントを追加したいのであれば

/usr/local/share/fonts/

の中にフォルダを作ってフォントを追加する。

その後

sudo fc-cache -fv

フォントのキャッシュを更新する。

font を追加して嬉しいこと

個人的に、Webkit2png などブラウザのフォント問題が解決する。

マイクロソフトのフォントなどをLinuxに入れて使う場合にはライセンス問題が出てくるので配慮すること。

でもMSゴシック無いと表示が崩れるWordファイルはどうすれば・・・

参考資料

http://askubuntu.com/questions/11130/how-can-i-convert-a-ppt-to-a-pdf-from-the-command-line

フォントライセンス関連

http://d.hatena.ne.jp/wakatono/20070216

ユーザーが画面を拡大しているか判定する

javascript で画面の拡大率を取得するには

window.innerWidth == document.width //拡大縮小しているか
window.innerWidth / document.width //拡大率
window.innerWidth / document.body.clientWidth // 最近はコッチ

window の幅とdocument の幅を比較すれば容易に取得できるました。

ただし、document.width は スマホでしか動かないので

 (document.width &&  document.width != window.innerWidth) || // iOS
 ( window.outerWidth && window.outerWidth !=  window.innerWidth ) //PC webkit

こんな感じにチェックするのが良いかもしれない。

ユーザーが 画面の拡大率は自由に決められます。

userscalable=no にするなんていうバッドノウハウが盛んに行われてて悔しい限りです。

userscalable=no にしないで スマホサイト作って欲しいなと思うです。

document.width って。

ブラウザに依ってサポートマチマチだね。document.width の有無でスマホPCと切り分け出来そうな・・・

2017/01/31 追記

iOS 10 くらいから、 document.width は動かなくなった。 document.documentElement.clientWidth を使う。

2017-08-17 追記

macトラックパッドによる拡大縮小はこの方法では検出できないので注意が必要。

function(){} と new Function

Function を使って関数を作る

Function のコンストラクタを使って関数を作る

var a = new Function("c", "return c");
a(1) //=>1

使い方

new Function ( 引数, 引数,,,, 関数本文)

ポイントは、全てを文字列で渡す点にある。

function(c){ return c } // おなじ

同じだが、文字列をeval せずに関数オブジェクトを作れる点が違う。eval と同等ですけどね。

apply/ call も出来る

Function コンストラクタが function を作るfunction であることに注目すると

apply

var a = Function.apply(null, ["c", "return c"])
a(1) //->1

call

var a = Function.call(null, "c", "return c")
a(1) //->1

のようなこともできるが、あまり使わない。function がなにか考えるのにちょうどいい。

Javascript のtypeof を少し調べてみた

js の typeof を調べた

すこし、思うところがあり、調べておいた。

判別式 結果
typeof 1 'number'
typeof "aaa" 'string'
typeof 0 'number'
typeof null 'object'
typeof undefined 'undefined'
typeof "" 'string'
typeof false 'boolean'
typeof true 'boolean'
typeof [] 'object'
typeof {} 'object'
typeof function(){} 'function'
typeof (function(){}) 'function'
typeof new (function(){}) 'object'
typeof Date 'function'
typeof Array 'function'
typeof Array.prototype 'object'
typeof NaN 'number'
typeof Infinity 'number'
typeof Error 'function'
typeof Math 'object'
typeof RegExp 'function'
typeof /aaa/ 'object'
typeof Promise 'function'
typeof Function 'function'
typeof Function() 'function'
typeof Function() () 'undefined'
typeof new Function 'function'
typeof new (new Function) 'object'

function とオブジェクトの境界線

typeof (function(){}) //=> function
typeof new (function(){}) //=> object
typeof new (new Function) //-> object

function は new 出来るしコンストラクタとして動作するので、 ここが境界線

new するとプロトタイプになるので

typeof Array //=>"function"
typeof Array.prototype //=>"object"

このあたりもおもしろい。ここから分かる通り、コンストラクタのprototypeには インスタンスを入れる。

function Human(name){
   this.name  = name
   this.say = function(){ console.log(this.name)}
}
function Lady(name){
  Human.call(this,name)
}
Lady.prototype = new Human
a =new Lady('yuri')
a.say()

こうやってみると、 nunber/ object / function /string / undefined / boolean くらいしか無いのがよく分かる。

null って object だけど、 toString出来ないんだよね不思議

function は全て new 出来るコンストラクタとして動作する。

MDNによると基本的なプリミティブな型は次の通り

  • Boolean
  • Null
  • Undefined
  • Number
  • String
  • Symbol (ES6)
  • Object

あれ。function ってプリミティブ型じゃないんだ。。。

参考資料

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures

Function.prototype.call() - JavaScript | MDN

JavaScriptで文字列化したfunction を実行する

eval しなくてもいい感じ

Function.call(this, "return "+ v  )();

javascript の深淵に触れた気がする

var a = {name:"takuya",say:function(){console.log(this.name)}}
//=>{ a: 'takuya', say: [Function] }
var b = a.say.toString()
//=>'function (){console.log(this.a)}'
var c = Function.call(null,"return "+b)()
c.call(a)
//=>takuya

Javascript は、関数の実行時にthis のコンテキストを次々と変えることが出来る。なのでデータと処理を一対一に対応させる「クラス」という概念は少し違った設計思想になっているようだ

js における this は不安定さがあるけど、慣れると便利だ。

var a = {name:"takuya"}
console.log_this = function(){ console.log(this) }
console.log_this() //=>Console {...}
// 関数をコピー
a.log = console.log_this
a.log()   //=>{ name: 'takuya', log: [Function] }
// 別オブジェクト
b = {name:"taro"}
a.log.call(b) //=>{ name: 'taro' }

関数は関数として単体で存在しているので、call を使えば、実行する主体を変えることが出来る。

これはこれで、便利なときと不便な時があるので好みの分かれる所。あまりコーディング規約で自由さを制限してしまうとJSで書く意味が薄れるのであまり制限してほしくないとも思う。