diff --git a/Library/Homebrew/cask/auditor.rb b/Library/Homebrew/cask/auditor.rb
index dcee4c4a9b9544204d816cb90e6cd1d9260e90f2..7abc4bb2c671af9aacdf809b9965a06bf556be5f 100644
--- a/Library/Homebrew/cask/auditor.rb
+++ b/Library/Homebrew/cask/auditor.rb
@@ -49,18 +49,16 @@ module Cask
     private
 
     def audit_all_languages
-      saved_languages = MacOS.instance_variable_get(:@languages)
-      begin
-        language_blocks.keys.all?(&method(:audit_languages))
-      ensure
-        MacOS.instance_variable_set(:@languages, saved_languages)
-      end
+      language_blocks.keys.all?(&method(:audit_languages))
     end
 
     def audit_languages(languages)
       ohai "Auditing language: #{languages.map { |lang| "'#{lang}'" }.to_sentence}"
-      MacOS.instance_variable_set(:@languages, languages)
-      audit_cask_instance(CaskLoader.load(cask.sourcefile_path))
+      localized_cask = CaskLoader.load(cask.sourcefile_path)
+      config = localized_cask.config
+      config.languages = languages
+      localized_cask.config = config
+      audit_cask_instance(localized_cask)
     end
 
     def audit_cask_instance(cask)
diff --git a/Library/Homebrew/cask/cmd.rb b/Library/Homebrew/cask/cmd.rb
index 139e0638877c2ad15d0b19f026687083779e75f0..de9215dc649c526b85ecaf5df5bc6758101475c4 100644
--- a/Library/Homebrew/cask/cmd.rb
+++ b/Library/Homebrew/cask/cmd.rb
@@ -65,8 +65,7 @@ module Cask
 
     option "--help", :help, false
 
-    # handled in OS::Mac
-    option "--language a,b,c", ->(*) {}
+    option "--language=a,b,c", ->(value) { Config.global.languages = value }
 
     # override default handling of --version
     option "--version", ->(*) { raise OptionParser::InvalidOption }
@@ -180,8 +179,6 @@ module Cask
     end
 
     def process_options(*args)
-      exclude_regex = /^--#{Regexp.union(*Config::DEFAULT_DIRS.keys.map(&Regexp.public_method(:escape)))}=/
-
       non_options = []
 
       if idx = args.index("--")
@@ -189,15 +186,32 @@ module Cask
         args = args.first(idx)
       end
 
+      exclude_regex = /^--#{Regexp.union(*Config::DEFAULT_DIRS.keys.map(&Regexp.public_method(:escape)))}=/
       cask_opts = Shellwords.shellsplit(ENV.fetch("HOMEBREW_CASK_OPTS", ""))
                             .reject { |arg| arg.match?(exclude_regex) }
 
       all_args = cask_opts + args
 
-      remaining = all_args.select do |arg|
-        !process_arguments([arg]).empty?
-      rescue OptionParser::InvalidOption, OptionParser::MissingArgument, OptionParser::AmbiguousOption
-        true
+      i = 0
+      remaining = []
+
+      while i < all_args.count
+        begin
+          arg = all_args[i]
+          next if process_arguments([arg]).empty?
+
+          remaining << arg
+        rescue OptionParser::MissingArgument
+          raise if i + 1 >= all_args.count
+
+          args = all_args[i..(i + 1)]
+          process_arguments(args)
+          i += 1
+        rescue OptionParser::InvalidOption
+          remaining << arg
+        end
+
+        i += 1
       end
 
       remaining + non_options
diff --git a/Library/Homebrew/cask/config.rb b/Library/Homebrew/cask/config.rb
index bd9bd711556a19e73a721985c1b8cebe59c69505..74c68bc24321c07c928dd42ea2f6b7d29a8a175a 100644
--- a/Library/Homebrew/cask/config.rb
+++ b/Library/Homebrew/cask/config.rb
@@ -2,6 +2,9 @@
 
 require "json"
 
+require "lazy_object"
+require "locale"
+
 require "extend/hash_validator"
 using HashValidator
 
@@ -24,6 +27,12 @@ module Cask
       screen_saverdir:      "~/Library/Screen Savers",
     }.freeze
 
+    def self.defaults
+      {
+        languages: LazyObject.new { MacOS.languages },
+      }.merge(DEFAULT_DIRS).freeze
+    end
+
     def self.global
       @global ||= new
     end
@@ -69,16 +78,16 @@ module Cask
     attr_accessor :explicit
 
     def initialize(default: nil, env: nil, explicit: {})
-      @default = self.class.canonicalize(DEFAULT_DIRS.merge(default)) if default
+      @default = self.class.canonicalize(self.class.defaults.merge(default)) if default
       @env = self.class.canonicalize(env) if env
       @explicit = self.class.canonicalize(explicit)
 
-      @env&.assert_valid_keys!(*DEFAULT_DIRS.keys)
-      @explicit.assert_valid_keys!(*DEFAULT_DIRS.keys)
+      @env&.assert_valid_keys!(*self.class.defaults.keys)
+      @explicit.assert_valid_keys!(*self.class.defaults.keys)
     end
 
     def default
-      @default ||= self.class.canonicalize(DEFAULT_DIRS)
+      @default ||= self.class.canonicalize(self.class.defaults)
     end
 
     def env
@@ -86,7 +95,16 @@ module Cask
         Shellwords.shellsplit(ENV.fetch("HOMEBREW_CASK_OPTS", ""))
                   .select { |arg| arg.include?("=") }
                   .map { |arg| arg.split("=", 2) }
-                  .map { |(flag, value)| [flag.sub(/^--/, ""), value] },
+                  .map do |(flag, value)|
+                    key = flag.sub(/^--/, "")
+
+                    if key == "language"
+                      key = "languages"
+                      value = value.split(",")
+                    end
+
+                    [key, value]
+                  end,
       )
     end
 
@@ -98,6 +116,24 @@ module Cask
       @manpagedir ||= HOMEBREW_PREFIX/"share/man"
     end
 
+    def languages
+      [
+        *explicit[:languages],
+        *env[:languages],
+        *default[:languages],
+      ].uniq.select do |lang|
+        # Ensure all languages are valid.
+        Locale.parse(lang)
+        true
+      rescue Locale::ParserError
+        false
+      end
+    end
+
+    def languages=(languages)
+      explicit[:languages] = languages
+    end
+
     DEFAULT_DIRS.each_key do |dir|
       define_method(dir) do
         explicit.fetch(dir, env.fetch(dir, default.fetch(dir)))
diff --git a/Library/Homebrew/cask/dsl.rb b/Library/Homebrew/cask/dsl.rb
index 525f927a2f5a229937a516a892a6fd8c16e6359a..ba5fc3cdf234b623c618b55c490ccacbe48cc113 100644
--- a/Library/Homebrew/cask/dsl.rb
+++ b/Library/Homebrew/cask/dsl.rb
@@ -137,13 +137,13 @@ module Cask
 
       raise CaskInvalidError.new(cask, "No default language specified.") if @language_blocks.default.nil?
 
-      locales = MacOS.languages
-                     .map do |language|
-                       Locale.parse(language)
-                     rescue Locale::ParserError
-                       nil
-                     end
-                     .compact
+      locales = cask.config.languages
+                    .map do |language|
+        Locale.parse(language)
+      rescue Locale::ParserError
+        nil
+      end
+                    .compact
 
       locales.each do |locale|
         key = locale.detect(@language_blocks.keys)
@@ -225,7 +225,7 @@ module Cask
     end
 
     def caskroom_path
-      @cask.caskroom_path
+      cask.caskroom_path
     end
 
     def staged_path
diff --git a/Library/Homebrew/os/mac.rb b/Library/Homebrew/os/mac.rb
index 8a854ab01f1f46b1fb3a4d8a44c989da7aaeb5f8..b44a47bcc441e1482cd44262819ceef29ff45e95 100644
--- a/Library/Homebrew/os/mac.rb
+++ b/Library/Homebrew/os/mac.rb
@@ -68,21 +68,7 @@ module OS
       end
       os_langs = os_langs.scan(/[^ \n"(),]+/)
 
-      @languages = [
-        *Homebrew.args.value("language")&.split(","),
-        *ENV["HOMEBREW_LANGUAGES"]&.split(","),
-        *os_langs,
-      ].uniq
-
-      # Ensure all languages are valid
-      @languages.select! do |lang|
-        Locale.parse(lang)
-        true
-      rescue Locale::ParserError
-        false
-      end
-
-      @languages
+      @languages = os_langs
     end
 
     def language
diff --git a/Library/Homebrew/test/cask/dsl_spec.rb b/Library/Homebrew/test/cask/dsl_spec.rb
index 24b4a06dc2ec9492cbddae39aca395214541bc8f..949a1c804f728add4f5c528682e8993b5db9a943 100644
--- a/Library/Homebrew/test/cask/dsl_spec.rb
+++ b/Library/Homebrew/test/cask/dsl_spec.rb
@@ -118,8 +118,8 @@ describe Cask::DSL, :cask do
   end
 
   describe "language stanza" do
-    it "allows multilingual casks" do
-      cask = lambda do
+    context "when language is set explicitly" do
+      subject(:cask) {
         Cask::Cask.new("cask-with-apps") do
           language "zh" do
             sha256 "abc123"
@@ -133,37 +133,65 @@ describe Cask::DSL, :cask do
 
           url "https://example.org/#{language}.zip"
         end
+      }
+
+      matcher :be_the_chinese_version do
+        match do |cask|
+          expect(cask.language).to eq("zh-CN")
+          expect(cask.sha256).to eq("abc123")
+          expect(cask.url.to_s).to eq("https://example.org/zh-CN.zip")
+        end
+      end
+
+      matcher :be_the_english_version do
+        match do |cask|
+          expect(cask.language).to eq("en-US")
+          expect(cask.sha256).to eq("xyz789")
+          expect(cask.url.to_s).to eq("https://example.org/en-US.zip")
+        end
+      end
+
+      before do
+        config = cask.config
+        config.languages = languages
+        cask.config = config
+      end
+
+      context "to 'zh'" do
+        let(:languages) { ["zh"] }
+
+        it { is_expected.to be_the_chinese_version }
+      end
+
+      context "to 'zh-XX'" do
+        let(:languages) { ["zh-XX"] }
+
+        it { is_expected.to be_the_chinese_version }
+      end
+
+      context "to 'en'" do
+        let(:languages) { ["en"] }
+
+        it { is_expected.to be_the_english_version }
       end
 
-      allow(MacOS).to receive(:languages).and_return(["zh"])
-      expect(cask.call.language).to eq("zh-CN")
-      expect(cask.call.sha256).to eq("abc123")
-      expect(cask.call.url.to_s).to eq("https://example.org/zh-CN.zip")
+      context "to 'xx-XX'" do
+        let(:languages) { ["xx-XX"] }
 
-      allow(MacOS).to receive(:languages).and_return(["zh-XX"])
-      expect(cask.call.language).to eq("zh-CN")
-      expect(cask.call.sha256).to eq("abc123")
-      expect(cask.call.url.to_s).to eq("https://example.org/zh-CN.zip")
+        it { is_expected.to be_the_english_version }
+      end
 
-      allow(MacOS).to receive(:languages).and_return(["en"])
-      expect(cask.call.language).to eq("en-US")
-      expect(cask.call.sha256).to eq("xyz789")
-      expect(cask.call.url.to_s).to eq("https://example.org/en-US.zip")
+      context "to 'xx-XX,zh,en'" do
+        let(:languages) { ["xx-XX", "zh", "en"] }
 
-      allow(MacOS).to receive(:languages).and_return(["xx-XX"])
-      expect(cask.call.language).to eq("en-US")
-      expect(cask.call.sha256).to eq("xyz789")
-      expect(cask.call.url.to_s).to eq("https://example.org/en-US.zip")
+        it { is_expected.to be_the_chinese_version }
+      end
 
-      allow(MacOS).to receive(:languages).and_return(["xx-XX", "zh", "en"])
-      expect(cask.call.language).to eq("zh-CN")
-      expect(cask.call.sha256).to eq("abc123")
-      expect(cask.call.url.to_s).to eq("https://example.org/zh-CN.zip")
+      context "to 'xx-XX,en-US,zh'" do
+        let(:languages) { ["xx-XX", "en-US", "zh"] }
 
-      allow(MacOS).to receive(:languages).and_return(["xx-XX", "en-US", "zh"])
-      expect(cask.call.language).to eq("en-US")
-      expect(cask.call.sha256).to eq("xyz789")
-      expect(cask.call.url.to_s).to eq("https://example.org/en-US.zip")
+        it { is_expected.to be_the_english_version }
+      end
     end
 
     it "returns an empty array if no languages are specified" do