Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nokorigi is always required #54

Closed
prodis opened this issue Nov 4, 2014 · 9 comments
Closed

Nokorigi is always required #54

prodis opened this issue Nov 4, 2014 · 9 comments

Comments

@prodis
Copy link
Contributor

prodis commented Nov 4, 2014

Nokogiri gem is required even if handler is configured with Ox.

@krasnoukhov
Copy link
Collaborator

At the moment nokogiri is required only if ox can't be loaded:

begin
SAXMachine.handler = :ox
rescue LoadError
SAXMachine.handler = :nokogiri
end

Am I missing something here?

@prodis
Copy link
Contributor Author

prodis commented Nov 4, 2014

I tried to use SAXMachine gem without install Nokogiri, only with Ox gem installed and I got a Nokogiri load error. This happens because lib/sax-machine/sax_document.rb file requires Nokogiri on top, in order to use it in parse method.

require "nokogiri"
module SAXMachine
def self.included(base)
base.send(:include, InstanceMethods)
base.extend(ClassMethods)
end
def parse(xml_text, on_error = nil, on_warning = nil)
if SAXMachine.handler == :ox
Ox.sax_parse(
SAXOxHandler.new(self, on_error, on_warning),
StringIO.new(xml_text),
{
symbolize: false,
convert_special: true,
skip: :skip_return,
}
)
else
handler = SAXNokogiriHandler.new(self, on_error, on_warning)
parser = Nokogiri::XML::SAX::Parser.new(handler)
parser.parse(xml_text) do |ctx|
ctx.replace_entities = true
end
end
self
end

@krasnoukhov
Copy link
Collaborator

Damn, you're right. I've removed this reference which was mistakenly left 🙅 Can you now try the master please?

@prodis
Copy link
Contributor Author

prodis commented Nov 5, 2014

Now, we can't instance Nokogiri::XML::SAX::Parser class in parse method.
https://github.com/pauldix/sax-machine/blob/master/lib/sax-machine/sax_document.rb#L20

How about my pull request #55?
I eliminated the if statement in parse method, created a factory class and extracted parser logic to handler manager classes. Only these classes require specific handler.
This way, if you need to use another handler in future, besides Nokogiri and Ox, you just need to create one or two specific handler classes, instead of to write a else or switch case statement in parse method.

@krasnoukhov
Copy link
Collaborator

Please consider following gist. As you can see, everything works fine and instance of Nokogiri::XML::SAX::Parser is created just fine. Another thing is that ox is not required on top of sax_document.rb, but Ox.sax_parse is called without any issue. This works because when you require something in Ruby, loaded modules/classes/constants are added to object space for a time of program execution, and we require at least one handler before sax_document.rb. Also, please note that tests are passing.

Regarding the #55, I think it's now clear that it does not actually solve the given problem. I see that your intention was to get rid from if or case statement with factory pattern. I personally must disagree with this approach. Ruby is not Java, and this case we're dealing with is very simple. We need to switch between handlers in only one place in code so using heavyweight abstraction seems like a bit an overhead for me. Please take a look at my attempt to add another handler option. As you can see, case statement still works for this case and also looks good and simple.

Please let me know what you think. Cheers 💫

@prodis
Copy link
Contributor Author

prodis commented Nov 6, 2014

About parsemethod you are right, Nokogiri is required on handler class, that is loaded when we choose the handler. My bad.

About the pull request #55, the point is exactly the obligation to modify the parse method implementation for each handler. This procedural approach goes against Open Closed Principle, besides the responsibility accumulation on SAXMachine class, where it knows specific parser logic of each handler. We don't need to use Java to apply object oriented design, we can do it in Ruby, after all everything is an object. But, your choice.

Can you release another version with the current master, please?

@krasnoukhov
Copy link
Collaborator

Your point is perfectly valid, so I went ahead and changed parse method to be unaware of handler logic.

@krasnoukhov
Copy link
Collaborator

1.0.3 is released. Please give it a try!

@prodis
Copy link
Contributor Author

prodis commented Nov 6, 2014

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants