Skip to content

Commit

Permalink
Replace ostruct with custom version
Browse files Browse the repository at this point in the history
Avoid future deprecations, behavior changes, and performance warnings.

Closes #1545
See #1525
  • Loading branch information
lsegal committed Sep 3, 2024
1 parent e458be0 commit 1694c3d
Show file tree
Hide file tree
Showing 18 changed files with 93 additions and 16 deletions.
23 changes: 23 additions & 0 deletions benchmarks/struct_vs_ostruct.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
require 'benchmark'
require 'ostruct'
require_relative '../lib/yard'

n = 100000
class MyStruct < Struct.new(:a, :b, :c); end
ostruct = OpenStruct.new
yostruct = YARD::OpenStruct.new
mystruct = MyStruct.new

Benchmark.bmbm do |x|
x.report("Struct.new(args)") { n.times { MyStruct.new 1, 2, 3 } }
x.report("Struct (assign)") { n.times { mystruct.a = 1 } }
x.report("Struct (read)") { n.times { mystruct.a } }
x.report("OpenStruct.new(args)") { n.times { OpenStruct.new a: 1, b: 2, c: 3 } }
x.report("OpenStruct.new (blank)") { n.times { OpenStruct.new } }
x.report("OpenStruct (assign)") { n.times { ostruct.a = 1 } }
x.report("OpenStruct (read)") { n.times { ostruct.a } }
x.report("YARD::OpenStruct.new(args)") { n.times { YARD::OpenStruct.new a: 1, b: 2, c: 3 } }
x.report("YARD::OpenStruct.new (blank)") { n.times { YARD::OpenStruct.new } }
x.report("YARD::OpenStruct (assign)") { n.times { yostruct.a = 1 } }
x.report("YARD::OpenStruct (read)") { n.times { yostruct.a } }
end
1 change: 1 addition & 0 deletions lib/yard/autoload.rb
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,7 @@ module Markup # Namespace for markup providers
autoload :DocstringParser, __p('docstring_parser')
autoload :GemIndex, __p('gem_index')
autoload :Logger, __p('logging')
autoload :OpenStruct, __p('open_struct')
autoload :Options, __p('options')
autoload :Registry, __p('registry')
autoload :RegistryResolver, __p('registry_resolver')
Expand Down
1 change: 0 additions & 1 deletion lib/yard/code_objects/macro_object.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
# frozen_string_literal: true
require 'ostruct'

module YARD
module CodeObjects
Expand Down
1 change: 0 additions & 1 deletion lib/yard/docstring_parser.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
# frozen_string_literal: true
require 'ostruct'

module YARD
# Parses text and creates a {Docstring} object to represent documentation
Expand Down
1 change: 0 additions & 1 deletion lib/yard/handlers/processor.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
# frozen_string_literal: true
require 'ostruct'

module YARD
module Handlers
Expand Down
66 changes: 66 additions & 0 deletions lib/yard/open_struct.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
module YARD
# An OpenStruct compatible struct class that allows for basic access of attributes
# via +struct.attr_name+ and +struct.attr_name = value+.
class OpenStruct
def initialize(hash = {})
@table = hash.each_pair { |k, v| [k.to_sym, v] }
end

# @private
def method_missing(name, *args)
if name.to_s.end_with?('=')
varname = name.to_s[0..-2].to_sym
__cache_lookup__(varname)
self[varname] = args.first
else
__cache_lookup__(name)
self[name]
end
end

def to_h
@table.dup
end

def ==(other)
other.is_a?(self.class) && to_h == other.to_h
end

def hash
@table.hash
end

def dig(*keys)
@table.dig(*keys)
end

def []=(key, value)
@table[key.to_sym] = value
end

def [](key)
@table[key.to_sym]
end

def each_pair(&block)
@table.each_pair(&block)
end

def marshal_dump
@table
end

def marshal_load(data)
@table = data
end

private

def __cache_lookup__(name)
instance_eval <<-RUBY, __FILE__, __LINE__ + 1
def #{name}; @table[:#{name}]; end
def #{name}=(v); @table[:#{name}] = v; end
RUBY
end
end
end
1 change: 0 additions & 1 deletion lib/yard/parser/source_parser.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# frozen_string_literal: true
require 'stringio'
require 'ostruct'

module YARD
module Parser
Expand Down
1 change: 0 additions & 1 deletion lib/yard/tags/directives.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
# frozen_string_literal: true
require 'ostruct'

module YARD
module Tags
Expand Down
1 change: 0 additions & 1 deletion lib/yard/templates/engine.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
# frozen_string_literal: true
require 'ostruct'

module YARD
module Templates
Expand Down
1 change: 0 additions & 1 deletion lib/yard/templates/template_options.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
# frozen_string_literal: true
require 'ostruct'

module YARD
module Templates
Expand Down
1 change: 0 additions & 1 deletion spec/cli/gems_spec.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
# frozen_string_literal: true
require 'ostruct'
require 'rubygems'

RSpec.describe YARD::CLI::Gems do
Expand Down
1 change: 0 additions & 1 deletion spec/handlers/base_spec.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# frozen_string_literal: true
require File.dirname(__FILE__) + '/spec_helper'
require 'ostruct'

include Parser

Expand Down
1 change: 0 additions & 1 deletion spec/handlers/dsl_handler_spec.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# frozen_string_literal: true
require File.dirname(__FILE__) + '/spec_helper'
require 'ostruct'

RSpec.describe "YARD::Handlers::Ruby::#{LEGACY_PARSER ? "Legacy::" : ""}DSLHandler" do
before(:all) { parse_file :dsl_handler_001, __FILE__ }
Expand Down
4 changes: 2 additions & 2 deletions spec/handlers/processor_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

RSpec.describe YARD::Handlers::Processor do
before do
@proc = Handlers::Processor.new(OpenStruct.new(:parser_type => :ruby))
@proc = Handlers::Processor.new(YARD::OpenStruct.new(:parser_type => :ruby))
end

it "starts with public visibility" do
Expand All @@ -19,7 +19,7 @@
end

it "has a globals structure" do
expect(@proc.globals).to be_a(OpenStruct)
expect(@proc.globals).to be_a(YARD::OpenStruct)
end

it "ignores HandlerAborted exceptions (but print debug info)" do
Expand Down
2 changes: 1 addition & 1 deletion spec/parser/source_parser_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ def after_file(&block)
it "handles basic callback support" do
before_list do |files, globals|
expect(files).to eq ['foo.rb', 'bar.rb']
expect(globals).to eq OpenStruct.new
expect(globals).to eq YARD::OpenStruct.new
end
parse_list ['foo.rb', 'foo!'], ['bar.rb', 'class Foo; end']
expect(Registry.at('Foo')).not_to be nil
Expand Down
1 change: 0 additions & 1 deletion spec/server/commands/library_command_spec.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
# frozen_string_literal: true
require 'ostruct'

RSpec.describe YARD::Server::Commands::LibraryCommand do
before do
Expand Down
1 change: 0 additions & 1 deletion spec/server/spec_helper.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
# frozen_string_literal: true
require 'ostruct'

include Server
include Commands
Expand Down
1 change: 0 additions & 1 deletion spec/templates/helpers/html_helper_spec.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# frozen_string_literal: true
require File.dirname(__FILE__) + "/shared_signature_examples"
require 'ostruct'

RSpec.describe YARD::Templates::Helpers::HtmlHelper do
include YARD::Templates::Helpers::BaseHelper
Expand Down

0 comments on commit 1694c3d

Please sign in to comment.