yegor256 / cactoos Goto Github PK
View Code? Open in Web Editor NEWObject-Oriented Java primitives, as an alternative to Google Guava and Apache Commons
Home Page: https://www.cactoos.org
License: MIT License
Object-Oriented Java primitives, as an alternative to Google Guava and Apache Commons
Home Page: https://www.cactoos.org
License: MIT License
Replace hand-made org.cactoos.Func
using everywhere to standard Java 8 java.util.function.Function
interface.
Let's create UncheckedScalar
, UncheckedText
, and UncheckedBytes
. Similar to UncheckedFunc
Let's create them.
Let's get rid of it, I don't like this design
Let's introduce two new classes PathAsInput
and PathAsOutput
, together with tests.
@yegor256 please, share somewhere Qulice
static code rules (preferable in README.md
file).
For me such errors are cryptic (at lease the first one)
[INFO] Checkstyle: src/main/java/org/cactoos/text/BlankText.java[63]: Using '++' is not allowed. (IllegalTokenCheck)
[INFO] Checkstyle: src/test/java/org/cactoos/text/BlankTextTest.java[47]: Indentation (20) must be same or less than previous line (12), or bigger by exactly 4 (CascadeIndentationCheck)
[INFO] Checkstyle: src/test/java/org/cactoos/text/BlankTextTest.java[61]: Indentation (20) must be same or less than previous line (12), or bigger by exactly 4 (CascadeIndentationCheck)
[INFO] Checkstyle: src/test/java/org/cactoos/text/BlankTextTest.java[75]: Indentation (20) must be same or less than previous line (12), or bigger by exactly 4 (CascadeIndentationCheck)
Let's build a FuncAsIterator.
Example, you want an Endless Iterator/Iterable of PrimeNumbers. You would do (pseudocode)
new Iterable(
new Iterator(
new PrimeFunc()
)
);
What should be the API of such a construct?
Should the Function that provides the next value take the last value as input, so the iterator would hold some state? Or should we have something new like a Provider that does not take input and hold his own state?
Once we get the API clear, i would like to contribute this.
@yegor256 can I create pull request with NotNullText? Or is it redundant?
new UpperText(new StringAsText(null)).asString();
new UpperText(new NotNullText(new StringAsText(null))).asString();
The puzzle 39-e7c34bd5
in src/main/java/org/cactoos/list/IterableAsList.java
(lines 56-58) has to be resolved: "Needs cached LengthOfIterable
version to improve IterableAsList
performance. Now each call to size()
goes through all iterable to calculate the size."
The puzzle was created by g4s8 on 27-May-17.
Estimate: 30 minutes, role: IMP.
If you have any technical questions, don't ask me, submit new tickets instead. The task will be "done" when the problem is fixed and the text of the puzzle is removed from the source code. Here is more about PDD and
about me.
Apache Commons has org.apache.commons.lang.StringUtils class with a set of helpful string static functions.
How such functions should be implemented in Cactoos? I see some approaches
BlankText
should be implemented with only one method boolean is()
. The development of this idea is introducing predicate interface.BlankText
class but it has to implement BooleanStatement
or Binary
interface with the single method boolean asBoolean()
Text
interface definition. Thus we can speak about smart java String
analog implementation.I don't like all of these approaches but the example is practical.
WDYT?
Let's add a class, which will do what ExceptionUtils
do in Apache Commons.
It'd be better to replace IOException with Exception.
What do you think?
Let's create classes for all methods from Apache StringUtils
.
Let's introduce new class Ternary. This will help in issue #36, for example.
Let's fix it.
Let's create a class that will be a Func
, but in case an exception is thrown, it will try to call a fallback Func
:
new FuncWithCallback<Integer, String>(
i -> {
if (i > 10) {
throw new Exception("Too much!");
}
return "Success";
},
ex -> {
System.out.printf("We just failed: %s", ex.getMessage());
return "Never mind";
}
)
Let's experiment and prove that it's possible.
Let's create two new classes, which will replace URLEncoder
and URLDecoder
from JDK. We will still use JDK, but these wrappers will be very helpful. At least they won't throw checked exceptions.
IoCheckedFunc
must not re-throw IOException
Under certain circumstances, remove() on a FilteredIterator removes the wrong element from the underlying iterator.
Reproduce:
Create List containing 0,1,2,3. (0,1,2,3)
Retrieve FilteredIterator over this List, set input-> true as filter function (no real filtering)
Retrieve first element (0).
Call hasNext() on FilteredIterator
call remove() on FilteredIterator
Expected: Check original List, it should not contain 0 anymore, but still have 1 in it. (1,2,3)
Actual: List does not contain 1 anymore (0,2,3)
I forked this repo and wrote a quick unit test to showcase this bug.
The unittest unfortunately does not follow single statement unit test since i don't know how to reproduce a multi-stage bug within a single statement.
What happens here is remove() Removes from the underlying collection the last element returned by this iterator (optional operation).
Since hasNext() on the FilteredIterator already calls next() on the underlying iterator. Because of that, the next-pointers" in the underlying and the filtered iterator diverge.
Therefore a subsequent remove() will call remove() on the underlying iterator, which already has returned the next element.
But since the next() was not called yet on the filteredIterator this behaviour is unexpected.
I tried to come up with a solution, but since the filter operation needs to look ahead in the underlying operator, i cannot see a way to offer the remove() operation. But luckily the remove() operation is an optional operation, we can just remove it. For that is opened a PR.
Tl;dR
FilteredIterator next pointer diverge from the underlying Iterators next pointer. Therefore the remove-method does not work as expected.
UnitTest here
PR which makes remove() a not supported operation here #83
In some ctors we have method calls for JDK's standard static
methods. E.g.
https://github.com/yegor256/cactoos/pull/22/files#diff-537f42dacf5c41ee51d8dc12c8560ce5R51
or
https://github.com/yegor256/cactoos/pull/22/files#diff-537f42dacf5c41ee51d8dc12c8560ce5R73
Also look on ctors in
https://github.com/yegor256/cactoos/blob/master/src/main/java/org/cactoos/text/FormattedText.java
in master
branch.
Sometimes we even have some non static JDK calls. E.g.
#20 (diff)
Question: have we avoid all of such method calls at all? So, literally,
Only
new
calls are available in ctors
rule everywhere?
It yes, have we avoid usage standard Arrays.asList
and Collections.unmodifiableSet
and create substitute for them?
Let's introduce new class Result (lazy evaluation). This class is necessary for #43.
I can see some non Latin (Cyrillic) chars in test string constants.
Can we avoid usage of the such chars without significant reason? E.g. I can see some ????
chars instead of Cyrillic chars in terminal while tests are running.
Cactoos intention, AFAIU, is to be a library (not a framework). So we have an issue with standard JDK entities interaction (strings, java statements, JDK functions etc.)
Here are 2 points: consuming some JDK entity and producing an entity to JDK.
The way for entity consuming shows StringAsText.java adapter. It adapts java.lang.String
into org.cactoos.Text
. So if we wanna use org.cactoos.text.UpperText
we have to write
new UpperText(new StringAsText("java string"))
The way for producing shows Scalar.java interface with it's asValue
method. E.g. LengthOfIterable
implements Scalar<Integer>
and should be used as
int length = new LengthOfIterable(...).asValue();
or
if (new IsBlank(new StringAsText("java string")).asValue()) {
...
}
For me the both producing and consuming look a bit cumbersome and verbose. Is there any way to make JDK interaction smoothly?
E.g. java.lang.CharSequence
interface might be used instead of org.cactoos.Text
and then string consuming might be looks like
new UpperText("some java literal")
as java.lang.String
already implements java.lang.CharSequence
interface.
Also, java.lang.Number
can be used as superclass of scalar values. However, instead of CharSequence
interface Number
is an abstract class and, thus, less helpful.
WDYT?
Repeat
design is not perfect
@yegor256 Usually, I don't like classes big classes and private methods, classes and constants. Why? Because without them, our classes are smaller and more cohesive. So, to achieve this goal, I suggest extract the TeeInput.Stream
class to a public TeeInputStream
class.
What do you think?
What java version is the library based?
In pom.xml I see
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
Does it mean the library isn't support java version less then 8?
If yes, why Func
interface was introduced than reuse java.util.function.Function
? Is it possible to use Java 8 streams in the library class implementations?
Let's create two new classes, all implementing Scalar<Boolean>
This kind of code is very procedural:
final File temp = File.createTempFile("cactoos-1", "txt-1");
temp.deleteOnExit();
So, let's do a not procedural temporary file creation/deletion.
in this chapter: https://github.com/yegor256/cactoos#textstrings
This class renamed by #38 to FormattedText
@yegor256 According to EO Vol. 1, page 53:
I call a manipulator a method that makes modifications to the real-world entity being abstracted by an object. It always returns void, and its names are always verbs.
So my sugestion is change the method's name from open()
to stream()
. I think it makes sense, because the method is returning an InputStream
.
What do you think?
Let's introduce predicates:
Neg (Negative)
LogConj (Logical conjunction)
with iterable
LogDisj (Logical disjunction)
with iterable
and may be
True
False
This will allow you to use complex conditions.
LengthOfIterable.asValue() can only be called once.
Subsequent calls will just return 0.
Reproduce:
Create an Instance of LengthOfIterator
Call asValue() twice and compare both results to see the results are different
Expected:
Both results be the same.
Test Code:
@Test
public void immuatableLength() {
LengthOfIterator length = new LengthOfIterator(
new ArrayAsIterable<String>("muh", "kuh").iterator()
);
MatcherAssert.assertThat("Iterator length should not change because of a call to asValue",
length.asValue() == length.asValue());
}
Let's add some contributors
ResourceAsInput throws Exception when the resource is not available. Instead, it must have an ability to do something more custom.
@yegor256 are you gonna put README.md
code examples into the project source code?
Let's introduce new class TextAsBytes, together with test. This will help add a test #14
FormattedText must use Text as pattern not a String.
Let's create SyncScalar
, SyncFunc
, SyncProc
Let's make sure that Text extends Comparable<Text>
Let's introduce new interface Pred (extends Func<X, Boolean>) that could be used to FilteredIterable, for example. This will add declarativeness and readability.
Let's add ProcAsRunnable
wrapper.
In README.md we can read:
How to use. The library has no dependencies. All you need is this (get the latest version here):
So, cactoos
depends on takes framework (in pom.xml
and UrlAsInputTest.java
) and this dependency should be removed.
Let's add one more optional argument to FuncWithCallback
, which will be applied if no exception is thrown.
@yegor256 @Englishman What do you think about them? Here you can see a discussion about this subject. I think very useful some classes to do it, how for example, to synchronize two threads, avoiding one to finish first than second.
Let's create a new interface Proc
I like how code examples look declarative. But there is a hidden issue with exceptions. Exceptions are goto statements to error handling block which is not composable and not object oriented.
The library does not give a way to declare how to handle errors. In some cases, it is good to terminate whole computation as soon as error occur, but other need some error handler that produces default value in place of failure.
This code will fail with IllegalStateException
if there is an IO problem with any file.
List<String> linesFromFiles =
new IterableAsList(
new ConcatenatedIterable(
new TransformedIterable<>(
new ArrayAsIterable<>("/tmp/a.txt", "/tmp/b.txt", "/tmp/c.txt"),
fileName ->
new TextAsLines(
new InputAsText(
new FileAsInput(
new File(fileName)
)
)
)
)
)
);
In order to change error handling strategy, in this specific example, I will need to write my custom implementation of InputAsText
that instead of throwing exception produce some default text. This approach is not scalable because it requires reimplementing every class that can throw an exception.
FP languages have a way to declare a function that produces either result or error without throwing exceptions using interface Either<ERROR, RESULT>.
What approach cactoos user should use for custom error handling?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.