スクリプト言語
スクリプト言語は、プログラムのソースコードを直接実行できる特徴を持つプログラミング言語群です。コンパイル不要な即時実行性、高い可読性、柔軟な型システムなどの特徴により、開発効率の向上に大きく貢献します。本稿では、主要なスクリプト言語の特徴と実践的な活用方法を解説します。
Perl
[編集]強力な正規表現エンジンと、豊富な組み込み関数を持つスクリプト言語です。システム管理やテキスト処理タスクで高い性能を発揮します。
#!/usr/bin/perl use v5.36; # スカラー変数 my $greeting = "Hello, Perl!"; say $greeting; # 数値演算 my $result = 10 + 3.14; printf "計算結果: %.2f\n", $result; # 配列 my @fruits = ('apple', 'banana', 'orange'); say "最初の果物: $fruits[0]"; say "配列の長さ: " . scalar(@fruits); # 配列操作 push @fruits, 'grape'; my $last_fruit = pop @fruits; say "取り出した果物: $last_fruit"; # ハッシュ(連想配列) my %user = ( name => 'Taro', age => 25, city => 'Tokyo' ); say "名前: $user{name}, 年齢: $user{age}"; # リファレンス my $fruits_ref = \@fruits; say "2番目の果物: " . $fruits_ref->[1]; # サブルーチン(関数)定義 sub greet { my ($name, $time) = @_; return "Good $time, $name!"; } say greet('Alice', 'morning'); # 正規表現 my $text = "The year is 2024 and the month is 12"; if ($text =~ /year is (\d+)/) { say "抽出した年: $1"; } # ファイル操作 open(my $fh, '>', 'test.txt') or die "ファイルを開けません: $!"; print $fh "これはテストです\n"; close $fh; # 例外処理 eval { die "エラーが発生しました\n"; }; if ($@) { say "捕捉したエラー: $@"; } # リスト処理 my @numbers = (1..5); my @squared = map { $_ * $_ } @numbers; say "二乗した数: " . join(', ', @squared); my @even = grep { $_ % 2 == 0 } @numbers; say "偶数: " . join(', ', @even); # 多言語対応 use utf8; use open ':encoding(utf8)'; my $japanese = "これは日本語です"; say $japanese; # ここ関数型プログラミング的な機能 my @words = qw(perl is a great language); my @caps = sort { length($b) <=> length($a) } map { ucfirst $_ } @words; say "変換後: " . join(' ', @caps); # オブジェクト指向 package Person; sub new { my ($class, $name) = @_; return bless { name => $name }, $class; } sub greet { my $self = shift; say "Hello, I'm " . $self->{name}; } my $person = Person->new("Bob"); $person->greet();
Ruby
[編集]Rubyは「プログラマの幸せ」を目的として開発された言語です。オブジェクト指向プログラミングを徹底し、ブロックやメタプログラミングなどの強力な機能を提供します。特にWeb開発フレームワークのRuby on Railsで知られています。
#!/usr/bin/env ruby # encoding: utf-8 # クラス定義とメソッド定義 class Animal # クラスメソッド def self.kingdom "Animalia" end # アクセサメソッド attr_accessor :name, :age # コンストラクタ def initialize(name, age) @name = name @age = age end # インスタンスメソッド def greet "こんにちは、#{@name}です。#{@age}歳です。" end end # 継承 class Dog < Animal # メソッドのオーバーライド def greet super + "ワンワン!" end end # モジュールの定義 module Swimmable def swim "水を泳いでいます" end end # mix-in class Fish < Animal include Swimmable end # ブロックとイテレータ def repeat_action(times) times.times do |i| yield i if block_given? end end # 例外処理 begin 1 / 0 rescue ZeroDivisionError => e puts "エラーが発生しました: #{e.message}" ensure puts "必ず実行される処理" end # 配列操作 fruits = %w(apple banana orange) fruits.map!(&:capitalize) puts "大文字にした果物: #{fruits.join(', ')}" # ハッシュ操作 user = { name: "太郎", age: 25, hobbies: ["読書", "旅行"] } # シンボル user[:location] = "東京" # メタプログラミング class MyClass def method_missing(method_name, *args) if method_name.to_s.start_with?('find_by_') attribute = method_name.to_s.sub('find_by_', '') "#{attribute}で検索中: #{args.first}" else super end end end # Procとラムダ greeting = ->(name) { "こんにちは、#{name}さん" } farewell = Proc.new { |name| "さようなら、#{name}さん" } # エンumerableモジュールの活用 numbers = (1..10).to_a even_numbers = numbers.select(&:even?) squared_numbers = numbers.map { |n| n ** 2 } # ファイル操作 File.open('test.txt', 'w') do |file| file.puts "Rubyのテストファイルです" end # 正規表現 text = "私の誕生日は1990年12月31日です" if text =~ /(\d{4})年(\d{1,2})月(\d{1,2})日/ puts "年: #{$1}, 月: #{$2}, 日: #{$3}" end # ブロック変数のスコープ sum = 0 [1, 2, 3].each do |n; sum| sum = n * 2 puts "ブロック内のsum: #{sum}" end puts "ブロック外のsum: #{sum}" # 真偽値の扱い puts "nilとfalse以外は真" if [nil, false, true, 0, "", [], {}].select(&:itself) # 文字列操作 string = "hello" puts string * 3 puts string.reverse puts string.chars.join('-') # メソッドの戻り値 def demonstrate_return return "早期リターン" if true "ここは実行されない" end # 実行例 dog = Dog.new("ポチ", 3) fish = Fish.new("ニモ", 1) puts dog.greet puts fish.swim puts Animal.kingdom repeat_action(3) { |i| puts "アクション#{i + 1}を実行" } my_class = MyClass.new puts my_class.find_by_name("太郎") puts greeting.call("花子") puts farewell.call("次郎") puts "偶数: #{even_numbers.join(', ')}" puts "二乗: #{squared_numbers.join(', ')}"
JavaScript
[編集]当初はブラウザ上でのみ動作する言語でしたが、Node.jsの登場により、サーバーサイドでも利用可能となりました。非同期処理を前提とした設計と、豊富なエコシステムが特徴です。
// モダンJavaScriptの機能紹介 // 変数宣言とスコープ let count = 0; const MAX_COUNT = 10; var legacyVar = "レガシーな宣言"; // 現代では非推奨 // テンプレートリテラル const name = "JavaScript"; console.log(`Hello, ${name}!`); // アロー関数 const add = (a, b) => a + b; const multiply = (a, b) => { console.log('乗算を実行します'); return a * b; }; // 分割代入 const person = { firstName: "太郎", lastName: "山田", age: 30 }; const { firstName, lastName } = person; const numbers = [1, 2, 3, 4, 5]; const [first, second, ...rest] = numbers; // クラスと継承 class Animal { constructor(name) { this.name = name; } speak() { return `${this.name}が鳴きます`; } static getType() { return "動物"; } } class Dog extends Animal { constructor(name, breed) { super(name); this.breed = breed; } speak() { return `${super.speak()} - ワンワン!`; } } // Promise と非同期処理 const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms)); async function demonstrateAsync() { console.log('開始'); await delay(1000); console.log('1秒経過'); try { const result = await Promise.all([ delay(500).then(() => '処理1'), delay(800).then(() => '処理2') ]); console.log('並列処理結果:', result); } catch (error) { console.error('エラー発生:', error); } } // イテレータとジェネレータ function* numberGenerator() { yield 1; yield 2; yield* [3, 4, 5]; } // MapとSet const userMap = new Map(); userMap.set('id1', { name: '田中', age: 25 }); userMap.set('id2', { name: '鈴木', age: 30 }); const uniqueNumbers = new Set([1, 1, 2, 2, 3, 3]); // 配列操作メソッド const fruits = ['りんご', 'バナナ', 'オレンジ']; const mappedFruits = fruits.map(fruit => fruit.toUpperCase()); const filteredFruits = fruits.filter(fruit => fruit.length > 3); const foundFruit = fruits.find(fruit => fruit === 'バナナ'); const sumArray = [1, 2, 3, 4].reduce((acc, curr) => acc + curr, 0); // オブジェクトの操作 const baseObject = { a: 1, b: 2 }; const newObject = { ...baseObject, c: 3 }; const keys = Object.keys(newObject); const values = Object.values(newObject); const entries = Object.entries(newObject); // モジュールパターン const Calculator = { add: (a, b) => a + b, subtract: (a, b) => a - b, multiply: (a, b) => a * b, divide: (a, b) => b !== 0 ? a / b : null }; // プロキシの使用 const handler = { get: (target, prop) => { console.log(`${prop}をアクセス中`); return target[prop]; } }; const proxyObject = new Proxy({x: 10, y: 20}, handler); // シンボルの使用 const uniqueKey = Symbol('説明'); const objWithSymbol = { [uniqueKey]: '特別な値' }; // WeakMapとWeakSet const weakMap = new WeakMap(); const weakSet = new WeakSet(); // 正規表現 const emailPattern = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/; const email = "test@example.com"; console.log(emailPattern.test(email)); // エラー処理 class CustomError extends Error { constructor(message) { super(message); this.name = 'CustomError'; } } // 実行例 const demonstrateFeatures = async () => { // クラスの使用 const dog = new Dog('ポチ', '柴犬'); console.log(dog.speak()); console.log(Animal.getType()); // 非同期処理 await demonstrateAsync(); // イテレータの使用 const generator = numberGenerator(); for (const num of generator) { console.log(num); } // Map/Setの使用 console.log(userMap.get('id1')); console.log(uniqueNumbers.size); // プロキシの動作確認 console.log(proxyObject.x); // エラーハンドリング try { throw new CustomError('カスタムエラーが発生しました'); } catch (error) { console.error(error.name, error.message); } }; // 機能のデモンストレーション実行 demonstrateFeatures().catch(console.error); // JSON操作 const jsonString = JSON.stringify(person); const parsedObject = JSON.parse(jsonString); // Intl APIの使用 const dateFormatter = new Intl.DateTimeFormat('ja-JP', { year: 'numeric', month: 'long', day: 'numeric' }); console.log(dateFormatter.format(new Date())); // Optional Chaining const deepObject = { level1: { level2: { level3: 'value' } } }; console.log(deepObject?.level1?.level2?.level3); // Nullish Coalescing const value = null; const defaultValue = value ?? 'デフォルト値';
シェルスクリプト
[編集]UNIXの思想を体現するスクリプト言語群です。主なシェルには、Bourne Shell (sh)、C SHell, Bash、Zsh、Korn Shell (ksh)などがあります。システムコマンドを組み合わせ、高度な自動化を実現します。
- sh
#!/bin/sh # bshクイックツアー # POSIXに準拠した移植性の高いシェルスクリプトの例 # 変数定義と代入 MESSAGE="Hello, Bourne Shell!" CURRENT_DATE=$(date +%Y-%m-%d) # 基本的な出力 echo "$MESSAGE on $CURRENT_DATE" echo "Script name: $0" echo "First argument: $1" echo "All arguments: $@" echo "Number of arguments: $#" # 制御構造:if文 check_number() { if [ "$1" -gt 0 ]; then echo "$1 は正の数です" elif [ "$1" -eq 0 ]; then echo "$1 はゼロです" else echo "$1 は負の数です" fi } # 制御構造:case文 get_day_type() { case "$1" in "Mon"|"Tue"|"Wed"|"Thu"|"Fri") echo "平日です" ;; "Sat"|"Sun") echo "週末です" ;; *) echo "不正な曜日です" ;; esac } # 制御構造:for文 echo "ファイル一覧:" for file in *; do if [ -f "$file" ]; then echo "ファイル: $file" elif [ -d "$file" ]; then echo "ディレクトリ: $file" fi done # 制御構造:while文 countdown() { local count=$1 while [ "$count" -gt 0 ]; do echo "カウントダウン: $count" count=$((count - 1)) sleep 1 done echo "完了!" } # 関数定義と引数の扱い process_file() { if [ $# -ne 1 ]; then echo "使用法: process_file ファイル名" return 1 fi if [ ! -f "$1" ]; then echo "エラー: $1 は通常のファイルではありません" return 2 fi echo "ファイル $1 を処理中..." cat "$1" return 0 } # 算術演算 calculate() { local a=$1 local b=$2 echo "加算: $((a + b))" echo "減算: $((a - b))" echo "乗算: $((a * b))" if [ "$b" -ne 0 ]; then echo "除算: $((a / b))" fi } # エラー処理 handle_error() { local exit_code=$? echo "エラーが発生しました。終了コード: $exit_code" exit "$exit_code" } trap handle_error ERR # パイプとリダイレクト create_test_file() { cat > testfile.txt << 'EOL' これは テスト用の ファイルです EOL } process_lines() { while IFS= read -r line; do echo "行の処理: $line" done } # 環境変数の操作 show_environment() { echo "PATH: $PATH" echo "HOME: $HOME" echo "USER: $USER" echo "SHELL: $SHELL" } # ファイルシステム操作 file_operations() { local testdir="testdir" if [ ! -d "$testdir" ]; then mkdir "$testdir" fi cd "$testdir" || exit touch "testfile.txt" echo "テストデータ" > "testfile.txt" ls -l cd .. rm -rf "$testdir" } # コマンド終了ステータスのチェック check_command() { if command -v "$1" > /dev/null 2>&1; then echo "$1 コマンドは利用可能です" return 0 else echo "$1 コマンドは見つかりません" return 1 fi } # メイン処理 main() { echo "=== bshクイックツアー開始 ===" check_number 5 check_number 0 check_number -3 get_day_type "Mon" get_day_type "Sun" countdown 3 create_test_file process_file "testfile.txt" calculate 10 5 show_environment file_operations check_command "ls" check_command "nonexistentcommand" echo "=== テスト終了 ===" } # スクリプトの実行 main "$@"
- csh
#!/bin/csh # C Shell クイックツアー # C言語に似た文法を持つシェルスクリプトの例 # 変数設定 set message = "Hello, C Shell!" set count = 1 set numbers = (1 2 3 4 5) set today = `date +%Y-%m-%d` # 環境変数の設定 setenv CUSTOM_VAR "custom value" # 配列の操作 set fruits = (apple banana orange) echo "First fruit: $fruits[1]" # C Shellは1から始まるインデックス echo "All fruits: $fruits" echo "Number of fruits: $#fruits" # エイリアスの定義 alias ll 'ls -l' alias greet 'echo "Hello, \!^"' # 制御構造:if-then-else if ($count < 5) then echo "countは5未満です" else if ($count == 5) then echo "countは5です" else echo "countは5より大きいです" endif # 制御構造:switch-case switch ($TERM) case "xterm*": echo "xtermターミナルです" breaksw case "vt100": echo "VT100ターミナルです" breaksw default: echo "その他のターミナルです" breaksw endsw # 制御構造:foreach foreach num ($numbers) echo "Number: $num" end # 制御構造:while set counter = 1 while ($counter <= 3) echo "Counter: $counter" @ counter++ end # 算術演算 @ result = 10 + 5 @ square = 5 ** 2 echo "10 + 5 = $result" echo "5の2乗 = $square" # 関数定義(C Shellではラベルとgotoを使用) start: echo "関数のような処理の開始" if ($?argv) then echo "引数: $argv" endif goto continue continue: echo "処理の続き" goto end # ファイル操作 if (! -d "testdir") then mkdir testdir endif cd testdir touch testfile.txt echo "テストデータ" > testfile.txt # ファイルテスト演算子 if (-f "testfile.txt") then echo "testfile.txtは通常のファイルです" endif if (-x "/bin/ls") then echo "/bin/lsは実行可能です" endif # 入力の処理 echo -n "お名前を入力してください: " set name = $< echo "こんにちは、$name さん" # パイプとフィルタ cat testfile.txt | grep "テスト" # ヒアドキュメント(C Shellの方式) cat << 'EOT' > config.txt 設定ファイル 項目1: 値1 項目2: 値2 EOT # 配列の操作と文字列処理 set words = (The quick brown fox) echo "単語数: $#words" echo "最後の単語: $words[$#words]" # 正規表現によるパターンマッチング if ("hello" =~ "h.*o") then echo "パターンにマッチしました" endif # エラーハンドリング onintr cleanup echo "割り込みを検知しました" cleanup: cd .. rm -rf testdir echo "クリーンアップ完了" # 特殊変数の使用 echo "スクリプト名: $0" echo "現在のシェル: $shell" echo "ホームディレクトリ: $home" # 終了処理 end: echo "スクリプトを終了します" exit 0
- ksh
#!/bin/ksh # 変数の定義 name="KornShell" version="93u+" # 関数の定義 greet_user() { echo "Hello, $1! Welcome to $name version $version." } # 配列の使用例 fruits=("apple" "banana" "cherry") echo "Fruits array: ${fruits[@]}" # ループの使用例 echo "Loop through fruits array:" for fruit in "${fruits[@]}"; do echo "Fruit: $fruit" done # 条件分岐 echo "Check if version is 93u+:" if [[ $version == "93u+" ]]; then echo "You're using the latest version!" else echo "Please update your KornShell." fi # コマンド置換の例 current_date=$(date) echo "Current date and time: $current_date" # パイプとリダイレクトの例 echo "Listing files in current directory:" ls | sort > sorted_files.txt # 退出ステータスの使用 exit_status=$? echo "The last command exit status: $exit_status" # 引数を使ったスクリプトの実行 if [[ $# -gt 0 ]]; then echo "Arguments passed to script: $@" else echo "No arguments passed." fi # 無限ループと中断 count=0 while true; do count=$((count + 1)) if [[ $count -ge 5 ]]; then echo "Breaking the loop after $count iterations." break fi done
- bash
#!/bin/bash # 変数の定義 name="Bash" version="5.1" # 関数の定義 greet_user() { echo "Hello, $1! Welcome to $name version $version." } # 配列の使用例 fruits=("apple" "banana" "cherry") echo "Fruits array: ${fruits[@]}" # ループの使用例 echo "Loop through fruits array:" for fruit in "${fruits[@]}"; do echo "Fruit: $fruit" done # 条件分岐 echo "Check if version is 5.1:" if [[ $version == "5.1" ]]; then echo "You're using the latest version!" else echo "Please update your Bash." fi # コマンド置換の例 current_date=$(date) echo "Current date and time: $current_date" # パイプとリダイレクトの例 echo "Listing files in current directory:" ls | sort > sorted_files.txt # 退出ステータスの使用 exit_status=$? echo "The last command exit status: $exit_status" # 引数を使ったスクリプトの実行 if [[ $# -gt 0 ]]; then echo "Arguments passed to script: $@" else echo "No arguments passed." fi # 無限ループと中断 count=0 while true; do count=$((count + 1)) if [[ $count -ge 5 ]]; then echo "Breaking the loop after $count iterations." break fi done
- zsh
#!/bin/zsh # 変数の定義 name="Zsh" version="5.9" # 関数の定義 greet_user() { echo "Hello, $1! Welcome to $name version $version." } # 配列の使用例 fruits=("apple" "banana" "cherry") echo "Fruits array: ${fruits[@]}" # ループの使用例 echo "Loop through fruits array:" for fruit in "${fruits[@]}"; do echo "Fruit: $fruit" done # 条件分岐 echo "Check if version is 5.9:" if [[ $version == "5.9" ]]; then echo "You're using the latest version!" else echo "Please update your Zsh." fi # コマンド置換の例 current_date=$(date) echo "Current date and time: $current_date" # パイプとリダイレクトの例 echo "Listing files in current directory:" ls | sort > sorted_files.txt # 退出ステータスの使用 exit_status=$? echo "The last command exit status: $exit_status" # 引数を使ったスクリプトの実行 if [[ $# -gt 0 ]]; then echo "Arguments passed to script: $@" else echo "No arguments passed." fi # 無限ループと中断 count=0 while true; do count=$((count + 1)) if [[ $count -ge 5 ]]; then echo "Breaking the loop after $count iterations." break fi done
Python
[編集]Pythonは「読みやすさ」を重視して設計されたスクリプト言語です。インデントによるブロック構造や豊富な組み込み型により、直感的なコーディングが可能です。科学技術計算、機械学習、Web開発など、幅広い分野で活用されています。
#!/usr/bin/env python3 # 変数の定義 name = "Python" version = "3.10" # 関数の定義 def greet_user(username): print(f"Hello, {username}! Welcome to {name} version {version}.") # 配列(リスト)の使用例 fruits = ["apple", "banana", "cherry"] print("Fruits list:", fruits) # ループの使用例 print("Loop through fruits list:") for fruit in fruits: print(f"Fruit: {fruit}") # 条件分岐 print("Check if version is 3.10:") if version == "3.10": print("You're using the latest version!") else: print("Please update your Python.") # コマンド置換(現在の日時を取得) import datetime current_date = datetime.datetime.now() print(f"Current date and time: {current_date}") # パイプとリダイレクト(ファイルに書き込む) with open("sorted_fruits.txt", "w") as file: sorted_fruits = sorted(fruits) file.write("\n".join(sorted_fruits)) # 退出ステータスの使用 exit_status = 0 # Pythonでは明示的にexitすることも可能ですが、通常はプログラムの終了でステータスコードが返されます print(f"The exit status is: {exit_status}") # 引数を使ったスクリプトの実行 import sys if len(sys.argv) > 1: print(f"Arguments passed to script: {sys.argv[1:]}") else: print("No arguments passed.") # 無限ループと中断 count = 0 while True: count += 1 if count >= 5: print(f"Breaking the loop after {count} iterations.") break
- まとめ
スクリプト言語は、その即時実行性と高い生産性により、現代のソフトウェア開発において重要な位置を占めています。各言語には独自の強みがあり、用途に応じて適切な選択をすることで、効率的な開発が可能となります。特に自動化やプロトタイピング、データ分析などの分野では、スクリプト言語の特徴を活かした開発が有効です。