Babel 6.xでErrorとかArrayをextendsしたときの挙動がおかしい

class FooError extends Error {}
console.log(new FooError() instanceof FooError); //=> false
console.log(new FooError() instanceof Error); //=> true

class FooArray extends Array {}
console.log(new FooArray() instanceof FooArray); //=> false
console.log(new FooArray() instanceof Array); //=> true

サポートしてないらしい。
https://phabricator.babeljs.io/T3083

GraphQLでNonNullなList

  1. フィールド自身がNonNull
  2. 要素がNonNull
  3. その両方

があって

let QueryType = new GraphQLObjectType({
  name: 'Query',
  fields: {
    list1: {
      type: new GraphQLNonNull(new GraphQLList(GraphQLString)),
      resolve: () => arr1,
    },
    list2: {
      type: new GraphQLList(new GraphQLNonNull(GraphQLString)),
      resolve: () => arr2,
    },
    list3: {
      type: new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(GraphQLString))),
      resolve: () => arr3,
    },
  },
});

GraphQLの型で表現するとこうなる。

type Query {
  list1: [String]!
  list2: [String!]
  list3: [String!]!
}

違いはこんな感じ

  • list1
    • null : NG
    • ['foo', null] : OK
    • [] : OK
  • list2
    • null : OK
    • ['foo', null] : NG
    • [] : OK
  • list3
    • null : NG
    • ['foo', null] : NG
    • [] : OK

module_function

moduleに普通にメソッドを定義するとインスタンスメソッドとして定義される。

module Foo
  def foo
  end

  puts instance_methods.include?(:foo)         #=> true
  puts private_instance_methods.include?(:foo) #=> false
  puts singleton_methods.include?(:foo)        #=> false
end

classにincludeして使う。

class Bar
  include Foo
end

Bar.new.foo

module_functionを使うと、instance_methodsから消えてprivate_instance_methodssingleton_methodsに追加される。

module Foo
  module_function
  def foo
  end

  puts instance_methods.include?(:foo)         #=> false
  puts private_instance_methods.include?(:foo) #=> true
  puts singleton_methods.include?(:foo)        #=> true
end

モジュールから直接呼んだり

Foo.foo

includeしたclassでレシーバーなしでアクセスできるようになる。

class Bar
  include Foo

  def hoge
    foo
  end
end

ただしpublicなインスタンスメソッドにはならない。

Bar.new.foo #=> NoMethodError

includeする使い方をしないのであればsingleton_methodだけ定義するだけでもいい。

module Foo
  def self.foo
  end

  puts instance_methods.include?(:foo)         #=> false
  puts private_instance_methods.include?(:foo) #=> true
  puts singleton_methods.include?(:foo)        #=> false
end
Foo.foo

FactoryGirlでActiveRecord以外のデータをつくる

例えばHashie::Mashを返したい場合はこんな感じ。

FactoryGirl.define do
  factory :post, class: Hashie::Mash do
    title "foo"
    body "bar"
  end
end

FactoryGirl.build(:post).class #=> Hashie::Mash
FactoryGirl.build(:post) #=> {"title"=>"foo", "body"=>"bar"}
FactoryGirl.build(:post, title: "baz").title #=> "baz"

ちなみにbuildじゃなくてcreateするとsave!が呼ばれるんだけどHashie::Mash#xxx!xxxフィールドが作られるという挙動なのでcreateでも動くけど無駄にsaveフィールドが作られる。

FactoryGirl.create(:post) #=> {"title"=>"foo", "body"=>"bar", "save" => {}}

ES6でN個の配列

Array.prototype.keysはIteratorを返すのでArray.fromに食わせる

Array.from(Array(5).keys()); //=> [0, 1, 2, 3, 4]

もしくは

Array.from({ length: 5 }).map((v, k) => k); //=> [0, 1, 2, 3, 4]

Array.fromの第二引数はmap的な役割があるので

Array.from({ length: 5 }, (v, k) => k); //=> [0, 1, 2, 3, 4]

こんな感じ。

[追記] 便利。

ES6でN個の配列 - hokaccha hamalog v3

これでも行ける -> [...Array(5).keys()];

2016/04/18 11:42
b.hatena.ne.jp

ShadowDOMの外から内部の要素を取得する

shadowRootでshadowRootが取れるのでそこから辿れる。

var proto = Object.create(HTMLElement.prototype);
proto.createdCallback = function() {
  var shadowRoot = this.createShadowRoot(); 
  shadowRoot.innerHTML = '<span class="foo">text</span>';
};

document.registerElement('x-element', { prototype: proto });

var el = document.createElement('x-element');

// これで取れる
console.log(el.shadowRoot.querySelector('.foo').textContent); //=> text