ITの隊長のブログ

ITの隊長のブログです。Rubyを使って仕事しています。最近も色々やっているお(^ω^ = ^ω^)

プログラミング言語によって、シングル・ダブルクォーテーションのどちらかで統一する必要はあるのか。調べてみた。

スポンサードリンク

http://www.flickr.com/photos/78637244@N00/5988163123
photo by BWJones



クォーテーションとは?

引用符(いんようふ)は、約物の一つ。文中において、他の文や語を引用していることを示す役割を果たす記号で、多くの場合一対で引用部分を囲む。コーテーションマーク、クォーテーションマーク、クオーテーションマーク、引用符号ともいう


引用符 - Wikipedia




プログラミングする時ってどっちで統一するか悩まない? 私はよく悩みます。言語によって、制限されることはありますが、最近の言語はどっちもおkな構文が多いので悩むんです。ちなみに同僚の一人はダブルクォーテーションを見つけたら、全部シングルに変えるらしい。


実は私もシングルクォーテーション派なんですよ。しかし、、、


PHP: 文字列 - Manual


注意: ダブルクォート 構文や heredoc 構文とは異なり、 変数と特殊文字のエスケープシーケンスは、 引用符 (シングルクオート) で括られた文字列にある場合には展開されません。


PHPはシングルクオートを利用すると変数、特殊文字が展開されません。その仕様で困らせたこともありました。30分ぐらい無駄にしたかな(´;ω;`)ブワッ


最初から言語の仕様を見極めた上で統一すればいいのでは? と、考えた私。そこで、これまで触ったことのある言語はどのクォーテーションで統一すれば扱いやすいのか。ちょっと調べみました。



前置き


その前に感じたこと。


変数展開のクォーテーションで統一すると処理速度が落ちるのでは?


調べた結果、この方の記事を読んで頂ければわかると思います。m(_ _ )m


takuya-1st.hatenablog.jp


特に問題ないらしい( ´ー`)フゥー...


※他プログラム言語は探してないけどね

各言語の仕様


これまで私が経験したことのある言語のみになります。


また、試す環境はブラウザのエディタみたいなサービスを使いました。


Web-based online coding environment | paiza.IO


C言語


Cはもうほとんど覚えていませんが、確かダブルじゃないとダメだったような覚えが・・・。


はい。その通りですね。

#include <stdio.h>
int main(void){
    // 文字列はダブルクォーテーション
    printf("ダブルクォーテーション\n");

    // 変数
    // マルチバイトはダブルクォーテーション
    char a[] = "シ";
    // ASCIIはシングル(ダブルにすると文字化け)
    char b = 'a';
    // 文字列はダブルクォーテーション
    char c[]= "abc";

    printf("ダブルクォーテーションです。 : %s\n", a);
    printf("シングルクォーテーションです : %c\n", b);
    printf("ダブルクォーテーションです。 : %s\n", c);
}


Cは型に厳しい(この表現は間違っていますが)ので、マルチバイト文字はダブルクォーテーションを使い、ASCII文字はシングルクォーテーションを使います。


Cの場合は使い分ける必要があります。

C#


C#も全然覚えていない。もう初心者です。

public class Hello{
    public static void Main(){

        // 文字列はダブルクォーテーション
        System.Console.WriteLine("double quotation C#");

        // char型はシングル
        char a = 'a';
        // マルチバイトでもおk
        char a = '';
        string b = "Hello World";

        // 特殊文字はダブル
        System.Console.WriteLine("a\tb");

        // おまけ 変数展開(?)
        System.Console.WriteLine("ようこそ {0}", b);
    }
}


C#もcharとstringで囲うクォーテーションをわけなきゃいけないですね。

Objective-C

#import <Foundation/Foundation.h>
int main(void){
    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];

    NSString *s = @"Double quotation.";
    [[NSFileHandle fileHandleWithStandardOutput] writeData: [s dataUsingEncoding: NSUTF8StringEncoding]];
    [pool release];
    return 0;
}


驚きました。去年まで使っていた言語なのに、初めて見たような感じがするのは私がおかしいのでしょうか。やっぱり見た目だけで難しいよObjective-C


確かChar型はなかったと思います。使いたいならC言語のCharにキャストして使ったような覚えが。。。まじで思い出せないorz


文字列はNSStringだけで使っていたような覚えがあります。シングルクォーテーションの出番はなさそう。

Java

public class Main {
    public static void main(String[] args) throws Exception {
        // ダブルクォーテーション
        System.out.println("Double quotation.");
        System.out.println('あ');

        char a = 'あ';
        String b = "あいうえお";

        // 特殊文字はダブルクォーテーション
        System.out.println("Hello\t World.");
        // 変数展開は無いのよね(知らないだけかも知れません・・・)
        System.out.println("Hello" + a + "World" + b);
    }
}


JavaC#と同じですね。(といいますか、JavaがそうだったらC#もそうでしょうね)

PHP


Webの味方。時には暗黙バグのぬか床。我らのPHP/(^o^)\\(^o^)/

<?php
    // ダブル・シングルどっちでもおk
    echo 'Single'.PHP_EOL;
    echo "Double and Single ok!".PHP_EOL;

    // 変数もどっちでもおk
    $a = 'a';
    $b = "b";

    // しかし、変数展開・特殊文字はダブルじゃなきゃダメ
    echo "$a + $b \t= ab\n";
    echo '$a + $b \t= ab\n';


PHPはダブルにしないとかな。

Python(Ver 2)


私の大好きな言語キタ━(゚∀゚)━!

# coding: utf-8

# ダブル・シングルおk
print 'Single'
print "Double"

# 変数もどっちもおk
a = 'a'
b = "b"
c = 'abc'
d = "abc"

# 変数展開・特殊文字もどっちでもおk(^ω^
print "%s\t%s" % (a, b)
print '%s\t%s' % (a, b)


Pythonからシングル派になった覚えがあります。そうか、こいつの影響だったのか。

Perl


ほとんど覚えていない言語。

# 変数はどっちもおk
my $a = 'A';
my $b = "b";
my $c = 'ab';
my $d = "ab";

# ダブルはおk、シングルはダメ
print "$a + $b\n";
print '$c + $d\n';


インタプリタ系統言語のほとんどは、どっちも併用はおkっぽいですね。ただし、出力系で併用NGと。
懐かしいなぁ。アクセスログ正規表現使いまくって集計した思ひ出。


Ruby


最近はじめました。

# どっちでもおk
puts 'Single quotation'
puts "Double quotation"

# どっちでもおk
a = 'single'
b = "double"

# rubyの場合変数展開は#{変数名}を使う
# またシングルクォーテーションは展開されない
puts 'a + \t#{b}'
puts "a + \t#{b}"


しかし、書きやすいなRuby恐ろしい子・・・!(°ω°;

JavaScript


いますごく人気ですよね。私も勉強中ですが、まだブラウザのイベントや実行タイミングに慣れません。

process.stdin.resume();
process.stdin.setEncoding('utf8');

// どっちでもおk
var a = "abcd";
var b = 'abcd';

//どっちでもおk(特殊文字も)
console.log(a + "ab\tcd");
console.log(b + 'ab\tcd');

Scala


ほとんど打ちこんだことはありません。

object Main extends App{

    // シングルクォーテーションはダメ
    // println('XXXXXXXX')
    println("XXX\tXXXXX")
}

Bash

#!/bin/bash

# シングル・ダブルどっちでもおkなんだけど
# 特殊文字はオプションを付与してあげないとダメ(コマンド依存)
echo -e 'Sing\tle'
echo -e "Doub\tle"

# 変数はどっちでもおk
VALIABLE_1='Sin\tgle'
VALIABLE_2="Dou\tble"

# 変数展開はシングルではダメ
echo -e 'Single : ${VALIABLE_1}'
echo -e "Double ${VALIABLE_2}"

MySQL


どうしてSQLまで追記したのかわかりません。後半だるくなったので 。。。かな?

create table Test(id integer, title varchar(100));
-- シングル、ダブルどっちでもおk
insert into Test(id, title) values(1, 'Hello'),(2, "Hello");
select * from Test;

世界のOSSはどっち派?


C、JavaとかObjective-Cは結論でているので、PHPとかPerlとかのOSSを見ていこうかなと思います。

CakePHPPHP

<?php
// 抜粋 ~/lib/Cake/Model/Permission.php 94行目
	if (!$acoPath) {
		$this->log(__d('cake_dev',
				"%s - Failed ACO node lookup in permissions check. Node references:\nAro: %s\nAco: %s",
				'DbAcl::check()',
				print_r($aro, true),
				print_r($aco, true)),
			E_USER_WARNING
		);
		return false;
	}

	if ($action !== '*' && !in_array('_' . $action, $permKeys)) {
		$this->log(__d('cake_dev', "ACO permissions key %s does not exist in %s", $action, 'DbAcl::check()'), E_USER_NOTICE);
		return false;
	}


へぇー、使い分けています。展開するべきところはダブルで、それ以外はシングルです。

RailsRuby


どうやらこっちも使い分けているっぽいぞ

# activerecord/lib/active_record/connection_adapters/postgresql/type_metadata.rb 14行目
def sql_type
    super.gsub(/\[\]$/, "")
  end

  def ==(other)
    other.is_a?(PostgreSQLTypeMetadata) &&
# actionview/lib/action_view/helpers/tags/base.rb 116行目
def sanitized_value(value)
      value.to_s.gsub(/\s/, "_").gsub(/[^-\w]/, "").downcase
    end

    def select_content_tag(option_tags, options, html_options)


・・・? そうではないのかな? なんか一貫性は見えないような。。。


箇所によって、似たようなコードでも、シングルとダブルがあるので、コミットした人それぞれで違うのかね。

Encode.pm (Perl)

# Encode.pm 62行目
sub encodings {
    my %enc;
    my $arg  = $_[1] || '';
    if ( $arg eq ":all" ) {
        %enc = ( %Encoding, %ExtModule );
    }
    else {
        %enc = %Encoding;
        for my $mod ( map { m/::/ ? $_ : "Encode::$_" } @_ ) {
            DEBUG and warn $mod;
            for my $enc ( keys %ExtModule ) {
                $ExtModule{$enc} eq $mod and $enc{$enc} = $mod;
            }
        }
    }
    return sort { lc $a cmp lc $b }
      grep      { !/^(?:Internal|Unicode|Guess)$/o } keys %enc;
}


打ち分けている・・・!?のかな。Perl難しい読めん。

Django (Python)


やっぱり読みやすい。Python

# django/django/utils/cache.py 171行目
def _i18n_cache_key_suffix(request, cache_key):
    """If necessary, adds the current locale or time zone to the cache key."""
    if settings.USE_I18N or settings.USE_L10N:
        # first check if LocaleMiddleware or another middleware added
        # LANGUAGE_CODE to request, then fall back to the active language
        # which in turn can also fall back to settings.LANGUAGE_CODE
        cache_key += '.%s' % getattr(request, 'LANGUAGE_CODE', get_language())
    if settings.USE_TZ:
        # The datetime module doesn't restrict the output of tzname().
        # Windows is known to use non-standard, locale-dependent names.
        # User-defined tzinfo classes may return absolutely anything.
        # Hence this paranoid conversion to create a valid cache key.
        tz_name = force_text(get_current_timezone_name(), errors='ignore')
        cache_key += '.%s' % tz_name.encode('ascii', 'ignore').decode('ascii').replace(' ', '_')
    return cache_key


ざっと見てみましたが、複数行文字列の場合はダブル、その他はシングルで統一されていました。

まとめ


結論


「統一することにこだわらず、自分の好きなコーディングをしたらいい。」になるんじゃないかな。 記述通り、こだわる前にコード書きなさいって感じですね。


私は使い分けるを前提に、このクォーテーションで統一していこうと思います。


f:id:aipacommander:20150519180346p:plain


個人的にはシングルがキレイに見えるので、シングルマスター(?)でいこうと思います。


長々書いたけど、以上。